This commit is contained in:
AJ Fontaine 2024-09-08 15:19:40 -04:00
commit 5e89e651e8
318 changed files with 7904 additions and 14430 deletions

View File

@ -11,6 +11,8 @@ on:
branches: branches:
- main # Trigger on pull request events targeting the main branch - main # Trigger on pull request events targeting the main branch
- beta # Trigger on pull request events targeting the beta branch - beta # Trigger on pull request events targeting the beta branch
merge_group:
types: [checks_requested]
jobs: jobs:
run-linters: # Define a job named "run-linters" run-linters: # Define a job named "run-linters"

View File

@ -8,6 +8,8 @@ on:
branches: branches:
- main - main
- beta - beta
merge_group:
types: [checks_requested]
jobs: jobs:
pages: pages:

View File

@ -11,10 +11,12 @@ on:
branches: branches:
- main # Trigger on pull request events targeting the main branch - main # Trigger on pull request events targeting the main branch
- beta # Trigger on pull request events targeting the beta branch - beta # Trigger on pull request events targeting the beta branch
merge_group:
types: [checks_requested]
jobs: jobs:
run-tests: # Define a job named "run-tests" run-misc-tests: # Define a job named "run-tests"
name: Run tests # Human-readable name for the job name: Run misc tests # Human-readable name for the job
runs-on: ubuntu-latest # Specify the latest Ubuntu runner for the job runs-on: ubuntu-latest # Specify the latest Ubuntu runner for the job
steps: steps:
@ -29,5 +31,75 @@ jobs:
- name: Install Node.js dependencies # Step to install Node.js dependencies - name: Install Node.js dependencies # Step to install Node.js dependencies
run: npm ci # Use 'npm ci' to install dependencies run: npm ci # Use 'npm ci' to install dependencies
- name: tests # Step to run tests - name: pre-test # pre-test to check overrides
run: npm run test:silent run: npx vitest run --project pre
- name: test misc
run: npx vitest --project misc
run-abilities-tests:
name: Run abilities tests
runs-on: ubuntu-latest
steps:
- name: Check out Git repository
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install Node.js dependencies
run: npm ci
- name: pre-test
run: npx vitest run --project pre
- name: test abilities
run: npx vitest --project abilities
run-items-tests:
name: Run items tests
runs-on: ubuntu-latest
steps:
- name: Check out Git repository
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install Node.js dependencies
run: npm ci
- name: pre-test
run: npx vitest run --project pre
- name: test items
run: npx vitest --project items
run-moves-tests:
name: Run moves tests
runs-on: ubuntu-latest
steps:
- name: Check out Git repository
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install Node.js dependencies
run: npm ci
- name: pre-test
run: npx vitest run --project pre
- name: test moves
run: npx vitest --project moves
run-battle-tests:
name: Run battle tests
runs-on: ubuntu-latest
steps:
- name: Check out Git repository
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install Node.js dependencies
run: npm ci
- name: pre-test
run: npx vitest run --project pre
- name: test battle
run: npx vitest --project battle

View File

@ -4,7 +4,8 @@ import { fileURLToPath } from 'url';
/** /**
* This script creates a test boilerplate file for a move or ability. * This script creates a test boilerplate file for a move or ability.
* @param {string} type - The type of test to create. Either "move" or "ability". * @param {string} type - The type of test to create. Either "move", "ability",
* or "item".
* @param {string} fileName - The name of the file to create. * @param {string} fileName - The name of the file to create.
* @example npm run create-test move tackle * @example npm run create-test move tackle
*/ */
@ -19,7 +20,7 @@ const type = args[0]; // "move" or "ability"
let fileName = args[1]; // The file name let fileName = args[1]; // The file name
if (!type || !fileName) { if (!type || !fileName) {
console.error('Please provide both a type ("move" or "ability") and a file name.'); console.error('Please provide both a type ("move", "ability", or "item") and a file name.');
process.exit(1); process.exit(1);
} }
@ -40,8 +41,11 @@ if (type === 'move') {
} else if (type === 'ability') { } else if (type === 'ability') {
dir = path.join(__dirname, 'src', 'test', 'abilities'); dir = path.join(__dirname, 'src', 'test', 'abilities');
description = `Abilities - ${formattedName}`; description = `Abilities - ${formattedName}`;
} else if (type === "item") {
dir = path.join(__dirname, 'src', 'test', 'items');
description = `Items - ${formattedName}`;
} else { } else {
console.error('Invalid type. Please use "move" or "ability".'); console.error('Invalid type. Please use "move", "ability", or "item".');
process.exit(1); process.exit(1);
} }

View File

@ -2,6 +2,15 @@ pre-commit:
parallel: true parallel: true
commands: commands:
eslint: eslint:
glob: '*.{js,jsx,ts,tsx}' glob: "*.{js,jsx,ts,tsx}"
run: npx eslint --fix {staged_files} run: npx eslint --fix {staged_files}
stage_fixed: true stage_fixed: true
skip:
- merge
- rebase
pre-push:
commands:
eslint:
glob: "*.{js,ts,jsx,tsx}"
run: npx eslint --fix {push_files}

View File

@ -0,0 +1,22 @@
{
"1": {
"529cc5": "8153c7",
"d65a94": "5ad662",
"3a73ad": "6b3aad",
"bd216b": "21bd69",
"5a193a": "195a2a",
"193a63": "391963",
"295a84": "472984"
},
"2": {
"529cc5": "ffedb6",
"d65a94": "e67d2f",
"3a73ad": "ebc582",
"bd216b": "b35131",
"31313a": "3d1519",
"5a193a": "752e2e",
"193a63": "705040",
"295a84": "ad875a",
"4a4a52": "57211a"
}
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

View File

@ -1691,8 +1691,8 @@
], ],
"465": [ "465": [
0, 0,
2, 1,
2 1
], ],
"466": [ "466": [
1, 1,
@ -3980,6 +3980,11 @@
1, 1,
1 1
], ],
"465": [
0,
1,
1
],
"592": [ "592": [
1, 1,
1, 1,
@ -5690,7 +5695,7 @@
"465": [ "465": [
0, 0,
1, 1,
2 1
], ],
"466": [ "466": [
2, 2,
@ -8008,6 +8013,11 @@
1, 1,
1 1
], ],
"465": [
0,
1,
1
],
"592": [ "592": [
1, 1,
1, 1,

View File

@ -8,5 +8,14 @@
"bd216b": "21bd69", "bd216b": "21bd69",
"31313a": "31313a", "31313a": "31313a",
"d65a94": "5ad662" "d65a94": "5ad662"
},
"2": {
"5a193a": "752e2e",
"31313a": "3d1519",
"d65a94": "e67d2f",
"3a73ad": "ebc582",
"295a84": "ad875a",
"bd216b": "b35131",
"193a63": "705040"
} }
} }

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

View File

@ -0,0 +1,21 @@
{
"1": {
"193a63": "391963",
"295a84": "472984",
"3a73ad": "6b3aad",
"000000": "000000",
"5a193a": "195a2a",
"bd216b": "21bd69",
"31313a": "31313a",
"d65a94": "5ad662"
},
"2": {
"5a193a": "752e2e",
"31313a": "3d1519",
"d65a94": "e67d2f",
"3a73ad": "ebc582",
"295a84": "ad875a",
"bd216b": "b35131",
"193a63": "705040"
}
}

View File

@ -0,0 +1,22 @@
{
"1": {
"529cc5": "8153c7",
"d65a94": "5ad662",
"3a73ad": "6b3aad",
"bd216b": "21bd69",
"5a193a": "195a2a",
"193a63": "391963",
"295a84": "472984"
},
"2": {
"529cc5": "ffedb6",
"d65a94": "e67d2f",
"3a73ad": "ebc582",
"bd216b": "b35131",
"31313a": "3d1519",
"5a193a": "752e2e",
"193a63": "705040",
"295a84": "ad875a",
"4a4a52": "57211a"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 B

View File

@ -1,3 +1,3 @@
import BattleScene from "#app/battle-scene.js"; import BattleScene from "#app/battle-scene";
export type ConditionFn = (scene: BattleScene, args?: any[]) => boolean; export type ConditionFn = (scene: BattleScene, args?: any[]) => boolean;

View File

@ -1,4 +1,4 @@
import { type enConfig } from "#app/locales/en/config.js"; import { type enConfig } from "#app/locales/en/config";
import { TOptions } from "i18next"; import { TOptions } from "i18next";
//TODO: this needs to be type properly in the future //TODO: this needs to be type properly in the future

View File

@ -63,7 +63,7 @@ import { Moves } from "#enums/moves";
import { PlayerGender } from "#enums/player-gender"; import { PlayerGender } from "#enums/player-gender";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { UiTheme } from "#enums/ui-theme"; import { UiTheme } from "#enums/ui-theme";
import { TimedEventManager } from "#app/timed-event-manager.js"; import { TimedEventManager } from "#app/timed-event-manager";
import i18next from "i18next"; import i18next from "i18next";
import { TrainerType } from "#enums/trainer-type"; import { TrainerType } from "#enums/trainer-type";
import { battleSpecDialogue } from "./data/dialogue"; import { battleSpecDialogue } from "./data/dialogue";
@ -130,7 +130,7 @@ export default class BattleScene extends SceneBase {
public gameSpeed: integer = 1; public gameSpeed: integer = 1;
public damageNumbersMode: integer = 0; public damageNumbersMode: integer = 0;
public reroll: boolean = false; public reroll: boolean = false;
public shopCursorTarget: number = ShopCursorTarget.CHECK_TEAM; public shopCursorTarget: number = ShopCursorTarget.REWARDS;
public showMovesetFlyout: boolean = true; public showMovesetFlyout: boolean = true;
public showArenaFlyout: boolean = true; public showArenaFlyout: boolean = true;
public showTimeOfDayWidget: boolean = true; public showTimeOfDayWidget: boolean = true;
@ -855,7 +855,7 @@ export default class BattleScene extends SceneBase {
overrideModifiers(this, false); overrideModifiers(this, false);
overrideHeldItems(this, pokemon, false); overrideHeldItems(this, pokemon, false);
if (boss && !dataSource) { if (boss && !dataSource) {
const secondaryIvs = Utils.getIvsFromId(Utils.randSeedInt(4294967295)); const secondaryIvs = Utils.getIvsFromId(Utils.randSeedInt(4294967296));
for (let s = 0; s < pokemon.ivs.length; s++) { for (let s = 0; s < pokemon.ivs.length; s++) {
pokemon.ivs[s] = Math.round(Phaser.Math.Linear(Math.min(pokemon.ivs[s], secondaryIvs[s]), Math.max(pokemon.ivs[s], secondaryIvs[s]), 0.75)); pokemon.ivs[s] = Math.round(Phaser.Math.Linear(Math.min(pokemon.ivs[s], secondaryIvs[s]), Math.max(pokemon.ivs[s], secondaryIvs[s]), 0.75));
@ -961,6 +961,16 @@ export default class BattleScene extends SceneBase {
this.offsetGym = this.gameMode.isClassic && this.getGeneratedOffsetGym(); this.offsetGym = this.gameMode.isClassic && this.getGeneratedOffsetGym();
} }
/**
* Generates a random number using the current battle's seed
*
* This calls {@linkcode Battle.randSeedInt}(`scene`, {@linkcode range}, {@linkcode min}) in `src/battle.ts`
* which calls {@linkcode Utils.randSeedInt randSeedInt}({@linkcode range}, {@linkcode min}) in `src/utils.ts`
*
* @param range How large of a range of random numbers to choose from. If {@linkcode range} <= 1, returns {@linkcode min}
* @param min The minimum integer to pick, default `0`
* @returns A random integer between {@linkcode min} and ({@linkcode min} + {@linkcode range} - 1)
*/
randBattleSeedInt(range: integer, min: integer = 0): integer { randBattleSeedInt(range: integer, min: integer = 0): integer {
return this.currentBattle?.randSeedInt(this, range, min); return this.currentBattle?.randSeedInt(this, range, min);
} }
@ -1112,7 +1122,8 @@ export default class BattleScene extends SceneBase {
doubleTrainer = false; doubleTrainer = false;
} }
} }
newTrainer = trainerData !== undefined ? trainerData.toTrainer(this) : new Trainer(this, trainerType, doubleTrainer ? TrainerVariant.DOUBLE : Utils.randSeedInt(2) ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT); const variant = doubleTrainer ? TrainerVariant.DOUBLE : (Utils.randSeedInt(2) ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT);
newTrainer = trainerData !== undefined ? trainerData.toTrainer(this) : new Trainer(this, trainerType, variant);
this.field.add(newTrainer); this.field.add(newTrainer);
} }
} }
@ -2620,7 +2631,7 @@ export default class BattleScene extends SceneBase {
if (mods.length < 1) { if (mods.length < 1) {
return mods; return mods;
} }
const rand = Math.floor(Utils.randSeedInt(mods.length)); const rand = Utils.randSeedInt(mods.length);
return [mods[rand], ...shuffleModifiers(mods.filter((_, i) => i !== rand))]; return [mods[rand], ...shuffleModifiers(mods.filter((_, i) => i !== rand))];
}; };
modifiers = shuffleModifiers(modifiers); modifiers = shuffleModifiers(modifiers);
@ -2742,6 +2753,35 @@ export default class BattleScene extends SceneBase {
(window as any).gameInfo = gameInfo; (window as any).gameInfo = gameInfo;
} }
/**
* This function retrieves the sprite and audio keys for active Pokemon.
* Active Pokemon include both enemy and player Pokemon of the current wave.
* Note: Questions on garbage collection go to @frutescens
* @returns a string array of active sprite and audio keys that should not be deleted
*/
getActiveKeys(): string[] {
const keys: string[] = [];
const playerParty = this.getParty();
playerParty.forEach(p => {
keys.push("pkmn__" + p.species.getSpriteId(p.gender === Gender.FEMALE, p.species.formIndex, p.shiny, p.variant));
keys.push("pkmn__" + p.species.getSpriteId(p.gender === Gender.FEMALE, p.species.formIndex, p.shiny, p.variant, true));
keys.push("cry/" + p.species.getCryKey(p.species.formIndex));
if (p.fusionSpecies && p.getSpeciesForm() !== p.getFusionSpeciesForm()) {
keys.push("cry/"+p.getFusionSpeciesForm().getCryKey(p.fusionSpecies.formIndex));
}
});
// enemyParty has to be operated on separately from playerParty because playerPokemon =/= enemyPokemon
const enemyParty = this.getEnemyParty();
enemyParty.forEach(p => {
keys.push(p.species.getSpriteKey(p.gender === Gender.FEMALE, p.species.formIndex, p.shiny, p.variant));
keys.push("cry/" + p.species.getCryKey(p.species.formIndex));
if (p.fusionSpecies && p.getSpeciesForm() !== p.getFusionSpeciesForm()) {
keys.push("cry/"+p.getFusionSpeciesForm().getCryKey(p.fusionSpecies.formIndex));
}
});
return keys;
}
/** /**
* Initialized the 2nd phase of the final boss (e.g. form-change for Eternatus) * Initialized the 2nd phase of the final boss (e.g. form-change for Eternatus)
* @param pokemon The (enemy) pokemon * @param pokemon The (enemy) pokemon

View File

@ -6,7 +6,7 @@ import Trainer, { TrainerVariant } from "./field/trainer";
import { GameMode } from "./game-mode"; import { GameMode } from "./game-mode";
import { MoneyMultiplierModifier, PokemonHeldItemModifier } from "./modifier/modifier"; import { MoneyMultiplierModifier, PokemonHeldItemModifier } from "./modifier/modifier";
import { PokeballType } from "./data/pokeball"; import { PokeballType } from "./data/pokeball";
import {trainerConfigs} from "#app/data/trainer-config"; import { trainerConfigs } from "#app/data/trainer-config";
import { ArenaTagType } from "#enums/arena-tag-type"; import { ArenaTagType } from "#enums/arena-tag-type";
import { BattleSpec } from "#enums/battle-spec"; import { BattleSpec } from "#enums/battle-spec";
import { Moves } from "#enums/moves"; import { Moves } from "#enums/moves";
@ -31,7 +31,7 @@ export enum BattlerIndex {
export interface TurnCommand { export interface TurnCommand {
command: Command; command: Command;
cursor?: integer; cursor?: number;
move?: QueuedMove; move?: QueuedMove;
targets?: BattlerIndex[]; targets?: BattlerIndex[];
skip?: boolean; skip?: boolean;
@ -39,38 +39,40 @@ export interface TurnCommand {
} }
interface TurnCommands { interface TurnCommands {
[key: integer]: TurnCommand | null [key: number]: TurnCommand | null
} }
export default class Battle { export default class Battle {
protected gameMode: GameMode; protected gameMode: GameMode;
public waveIndex: integer; public waveIndex: number;
public battleType: BattleType; public battleType: BattleType;
public battleSpec: BattleSpec; public battleSpec: BattleSpec;
public trainer: Trainer | null; public trainer: Trainer | null;
public enemyLevels: integer[] | undefined; public enemyLevels: number[] | undefined;
public enemyParty: EnemyPokemon[]; public enemyParty: EnemyPokemon[] = [];
public seenEnemyPartyMemberIds: Set<integer>; public seenEnemyPartyMemberIds: Set<number> = new Set<number>();
public double: boolean; public double: boolean;
public started: boolean; public started: boolean = false;
public enemySwitchCounter: integer; public enemySwitchCounter: number = 0;
public turn: integer; public turn: number = 0;
public turnCommands: TurnCommands; public turnCommands: TurnCommands;
public playerParticipantIds: Set<integer>; public playerParticipantIds: Set<number> = new Set<number>();
public battleScore: integer; public battleScore: number = 0;
public postBattleLoot: PokemonHeldItemModifier[]; public postBattleLoot: PokemonHeldItemModifier[] = [];
public escapeAttempts: integer; public escapeAttempts: number = 0;
public lastMove: Moves; public lastMove: Moves;
public battleSeed: string; public battleSeed: string = Utils.randomString(16, true);
private battleSeedState: string | null; private battleSeedState: string | null = null;
public moneyScattered: number; public moneyScattered: number = 0;
public lastUsedPokeball: PokeballType | null; public lastUsedPokeball: PokeballType | null = null;
public playerFaints: number; // The amount of times pokemon on the players side have fainted /** The number of times a Pokemon on the player's side has fainted this battle */
public enemyFaints: number; // The amount of times pokemon on the enemies side have fainted public playerFaints: number = 0;
/** The number of times a Pokemon on the enemy's side has fainted this battle */
public enemyFaints: number = 0;
private rngCounter: integer = 0; private rngCounter: number = 0;
constructor(gameMode: GameMode, waveIndex: integer, battleType: BattleType, trainer?: Trainer, double?: boolean) { constructor(gameMode: GameMode, waveIndex: number, battleType: BattleType, trainer?: Trainer, double?: boolean) {
this.gameMode = gameMode; this.gameMode = gameMode;
this.waveIndex = waveIndex; this.waveIndex = waveIndex;
this.battleType = battleType; this.battleType = battleType;
@ -79,22 +81,7 @@ export default class Battle {
this.enemyLevels = battleType !== BattleType.TRAINER this.enemyLevels = battleType !== BattleType.TRAINER
? new Array(double ? 2 : 1).fill(null).map(() => this.getLevelForWave()) ? new Array(double ? 2 : 1).fill(null).map(() => this.getLevelForWave())
: trainer?.getPartyLevels(this.waveIndex); : trainer?.getPartyLevels(this.waveIndex);
this.enemyParty = []; this.double = double ?? false;
this.seenEnemyPartyMemberIds = new Set<integer>();
this.double = !!double;
this.enemySwitchCounter = 0;
this.turn = 0;
this.playerParticipantIds = new Set<integer>();
this.battleScore = 0;
this.postBattleLoot = [];
this.escapeAttempts = 0;
this.started = false;
this.battleSeed = Utils.randomString(16, true);
this.battleSeedState = null;
this.moneyScattered = 0;
this.lastUsedPokeball = null;
this.playerFaints = 0;
this.enemyFaints = 0;
} }
private initBattleSpec(): void { private initBattleSpec(): void {
@ -105,7 +92,7 @@ export default class Battle {
this.battleSpec = spec; this.battleSpec = spec;
} }
private getLevelForWave(): integer { private getLevelForWave(): number {
const levelWaveIndex = this.gameMode.getWaveForDifficulty(this.waveIndex); const levelWaveIndex = this.gameMode.getWaveForDifficulty(this.waveIndex);
const baseLevel = 1 + levelWaveIndex / 2 + Math.pow(levelWaveIndex / 25, 2); const baseLevel = 1 + levelWaveIndex / 2 + Math.pow(levelWaveIndex / 25, 2);
const bossMultiplier = 1.2; const bossMultiplier = 1.2;
@ -138,7 +125,7 @@ export default class Battle {
return rand / value; return rand / value;
} }
getBattlerCount(): integer { getBattlerCount(): number {
return this.double ? 2 : 1; return this.double ? 2 : 1;
} }
@ -367,7 +354,13 @@ export default class Battle {
return null; return null;
} }
randSeedInt(scene: BattleScene, range: integer, min: integer = 0): integer { /**
* Generates a random number using the current battle's seed. Calls {@linkcode Utils.randSeedInt}
* @param range How large of a range of random numbers to choose from. If {@linkcode range} <= 1, returns {@linkcode min}
* @param min The minimum integer to pick, default `0`
* @returns A random integer between {@linkcode min} and ({@linkcode min} + {@linkcode range} - 1)
*/
randSeedInt(scene: BattleScene, range: number, min: number = 0): number {
if (range <= 1) { if (range <= 1) {
return min; return min;
} }
@ -392,7 +385,7 @@ export default class Battle {
} }
export class FixedBattle extends Battle { export class FixedBattle extends Battle {
constructor(scene: BattleScene, waveIndex: integer, config: FixedBattleConfig) { constructor(scene: BattleScene, waveIndex: number, config: FixedBattleConfig) {
super(scene.gameMode, waveIndex, config.battleType, config.battleType === BattleType.TRAINER ? config.getTrainer(scene) : undefined, config.double); super(scene.gameMode, waveIndex, config.battleType, config.battleType === BattleType.TRAINER ? config.getTrainer(scene) : undefined, config.double);
if (config.getEnemyParty) { if (config.getEnemyParty) {
this.enemyParty = config.getEnemyParty(scene); this.enemyParty = config.getEnemyParty(scene);
@ -408,7 +401,7 @@ export class FixedBattleConfig {
public double: boolean; public double: boolean;
public getTrainer: GetTrainerFunc; public getTrainer: GetTrainerFunc;
public getEnemyParty: GetEnemyPartyFunc; public getEnemyParty: GetEnemyPartyFunc;
public seedOffsetWaveIndex: integer; public seedOffsetWaveIndex: number;
setBattleType(battleType: BattleType): FixedBattleConfig { setBattleType(battleType: BattleType): FixedBattleConfig {
this.battleType = battleType; this.battleType = battleType;
@ -430,7 +423,7 @@ export class FixedBattleConfig {
return this; return this;
} }
setSeedOffsetWave(seedOffsetWaveIndex: integer): FixedBattleConfig { setSeedOffsetWave(seedOffsetWaveIndex: number): FixedBattleConfig {
this.seedOffsetWaveIndex = seedOffsetWaveIndex; this.seedOffsetWaveIndex = seedOffsetWaveIndex;
return this; return this;
} }
@ -476,7 +469,7 @@ function getRandomTrainerFunc(trainerPool: (TrainerType | TrainerType[])[], rand
} }
export interface FixedBattleConfigs { export interface FixedBattleConfigs {
[key: integer]: FixedBattleConfig [key: number]: FixedBattleConfig
} }
/** /**
* Youngster/Lass on 5 * Youngster/Lass on 5

View File

@ -1,4 +1,4 @@
import {SettingGamepad} from "#app/system/settings/settings-gamepad.js"; import {SettingGamepad} from "#app/system/settings/settings-gamepad";
import {Button} from "#enums/buttons"; import {Button} from "#enums/buttons";
/** /**

64
src/data/ability.ts Normal file → Executable file
View File

@ -310,7 +310,7 @@ export class ReceivedMoveDamageMultiplierAbAttr extends PreDefendAbAttr {
export class ReceivedTypeDamageMultiplierAbAttr extends ReceivedMoveDamageMultiplierAbAttr { export class ReceivedTypeDamageMultiplierAbAttr extends ReceivedMoveDamageMultiplierAbAttr {
constructor(moveType: Type, damageMultiplier: number) { constructor(moveType: Type, damageMultiplier: number) {
super((user, target, move) => move.type === moveType, damageMultiplier); super((target, user, move) => user.getMoveType(move) === moveType, damageMultiplier);
} }
} }
@ -455,7 +455,7 @@ export class NonSuperEffectiveImmunityAbAttr extends TypeImmunityAbAttr {
} }
applyPreDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, cancelled: Utils.BooleanHolder, args: any[]): boolean { applyPreDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, cancelled: Utils.BooleanHolder, args: any[]): boolean {
if (move instanceof AttackMove && pokemon.getAttackTypeEffectiveness(pokemon.getMoveType(move), attacker) < 2) { if (move instanceof AttackMove && pokemon.getAttackTypeEffectiveness(attacker.getMoveType(move), attacker) < 2) {
cancelled.value = true; // Suppresses "No Effect" message cancelled.value = true; // Suppresses "No Effect" message
(args[0] as Utils.NumberHolder).value = 0; (args[0] as Utils.NumberHolder).value = 0;
return true; return true;
@ -1085,7 +1085,7 @@ export class PostDefendMoveDisableAbAttr extends PostDefendAbAttr {
} }
applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean { applyPostDefend(pokemon: Pokemon, passive: boolean, simulated: boolean, attacker: Pokemon, move: Move, hitResult: HitResult, args: any[]): boolean {
if (!attacker.summonData.disabledMove) { if (attacker.getTag(BattlerTagType.DISABLED) === null) {
if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && (this.chance === -1 || pokemon.randSeedInt(100) < this.chance) && !attacker.isMax()) { if (move.checkFlag(MoveFlags.MAKES_CONTACT, attacker, pokemon) && (this.chance === -1 || pokemon.randSeedInt(100) < this.chance) && !attacker.isMax()) {
if (simulated) { if (simulated) {
return true; return true;
@ -1093,21 +1093,12 @@ export class PostDefendMoveDisableAbAttr extends PostDefendAbAttr {
this.attacker = attacker; this.attacker = attacker;
this.move = move; this.move = move;
this.attacker.addTag(BattlerTagType.DISABLED, 4, 0, pokemon.id);
attacker.summonData.disabledMove = move.id;
attacker.summonData.disabledTurns = 4;
return true; return true;
} }
} }
return false; return false;
} }
getTriggerMessage(pokemon: Pokemon, abilityName: string, ...args: any[]): string {
return i18next.t("abilityTriggers:postDefendMoveDisable", {
pokemonNameWithAffix: getPokemonNameWithAffix(this.attacker),
moveName: this.move.name,
});
}
} }
export class PostStatStageChangeStatStageChangeAbAttr extends PostStatStageChangeAbAttr { export class PostStatStageChangeStatStageChangeAbAttr extends PostStatStageChangeAbAttr {
@ -1462,7 +1453,7 @@ export class MovePowerBoostAbAttr extends VariableMovePowerAbAttr {
export class MoveTypePowerBoostAbAttr extends MovePowerBoostAbAttr { export class MoveTypePowerBoostAbAttr extends MovePowerBoostAbAttr {
constructor(boostedType: Type, powerMultiplier?: number) { constructor(boostedType: Type, powerMultiplier?: number) {
super((pokemon, defender, move) => move.type === boostedType, powerMultiplier || 1.5); super((pokemon, defender, move) => pokemon?.getMoveType(move) === boostedType, powerMultiplier || 1.5);
} }
} }
@ -1546,7 +1537,7 @@ export class PreAttackFieldMoveTypePowerBoostAbAttr extends FieldMovePowerBoostA
* @param powerMultiplier - The multiplier to apply to the move's power, defaults to 1.5 if not provided. * @param powerMultiplier - The multiplier to apply to the move's power, defaults to 1.5 if not provided.
*/ */
constructor(boostedType: Type, powerMultiplier?: number) { constructor(boostedType: Type, powerMultiplier?: number) {
super((pokemon, defender, move) => move.type === boostedType, powerMultiplier || 1.5); super((pokemon, defender, move) => pokemon?.getMoveType(move) === boostedType, powerMultiplier || 1.5);
} }
} }
@ -2651,7 +2642,7 @@ export class ConfusionOnStatusEffectAbAttr extends PostAttackAbAttr {
if (simulated) { if (simulated) {
return defender.canAddTag(BattlerTagType.CONFUSED); return defender.canAddTag(BattlerTagType.CONFUSED);
} else { } else {
return defender.addTag(BattlerTagType.CONFUSED, pokemon.randSeedInt(3, 2), move.id, defender.id); return defender.addTag(BattlerTagType.CONFUSED, pokemon.randSeedIntRange(2, 5), move.id, defender.id);
} }
} }
return false; return false;
@ -5100,9 +5091,9 @@ export function initAbilities() {
.ignorable(), .ignorable(),
new Ability(Abilities.TINTED_LENS, 4) new Ability(Abilities.TINTED_LENS, 4)
//@ts-ignore //@ts-ignore
.attr(DamageBoostAbAttr, 2, (user, target, move) => target.getAttackTypeEffectiveness(move.type, user) <= 0.5), // TODO: fix TS issues .attr(DamageBoostAbAttr, 2, (user, target, move) => target?.getMoveEffectiveness(user, move) <= 0.5), // TODO: fix TS issues
new Ability(Abilities.FILTER, 4) new Ability(Abilities.FILTER, 4)
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => target.getAttackTypeEffectiveness(move.type, user) >= 2, 0.75) .attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => target.getMoveEffectiveness(user, move) >= 2, 0.75)
.ignorable(), .ignorable(),
new Ability(Abilities.SLOW_START, 4) new Ability(Abilities.SLOW_START, 4)
.attr(PostSummonAddBattlerTagAbAttr, BattlerTagType.SLOW_START, 5), .attr(PostSummonAddBattlerTagAbAttr, BattlerTagType.SLOW_START, 5),
@ -5118,7 +5109,7 @@ export function initAbilities() {
.attr(PostWeatherLapseHealAbAttr, 1, WeatherType.HAIL, WeatherType.SNOW) .attr(PostWeatherLapseHealAbAttr, 1, WeatherType.HAIL, WeatherType.SNOW)
.partial(), // Healing not blocked by Heal Block .partial(), // Healing not blocked by Heal Block
new Ability(Abilities.SOLID_ROCK, 4) new Ability(Abilities.SOLID_ROCK, 4)
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => target.getAttackTypeEffectiveness(move.type, user) >= 2, 0.75) .attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => target.getMoveEffectiveness(user, move) >= 2, 0.75)
.ignorable(), .ignorable(),
new Ability(Abilities.SNOW_WARNING, 4) new Ability(Abilities.SNOW_WARNING, 4)
.attr(PostSummonWeatherChangeAbAttr, WeatherType.SNOW) .attr(PostSummonWeatherChangeAbAttr, WeatherType.SNOW)
@ -5236,10 +5227,13 @@ export function initAbilities() {
new Ability(Abilities.MOXIE, 5) new Ability(Abilities.MOXIE, 5)
.attr(PostVictoryStatStageChangeAbAttr, Stat.ATK, 1), .attr(PostVictoryStatStageChangeAbAttr, Stat.ATK, 1),
new Ability(Abilities.JUSTIFIED, 5) new Ability(Abilities.JUSTIFIED, 5)
.attr(PostDefendStatStageChangeAbAttr, (target, user, move) => move.type === Type.DARK && move.category !== MoveCategory.STATUS, Stat.ATK, 1), .attr(PostDefendStatStageChangeAbAttr, (target, user, move) => user.getMoveType(move) === Type.DARK && move.category !== MoveCategory.STATUS, Stat.ATK, 1),
new Ability(Abilities.RATTLED, 5) new Ability(Abilities.RATTLED, 5)
.attr(PostDefendStatStageChangeAbAttr, (target, user, move) => move.category !== MoveCategory.STATUS && (move.type === Type.DARK || move.type === Type.BUG || .attr(PostDefendStatStageChangeAbAttr, (target, user, move) => {
move.type === Type.GHOST), Stat.SPD, 1) const moveType = user.getMoveType(move);
return move.category !== MoveCategory.STATUS
&& (moveType === Type.DARK || moveType === Type.BUG || moveType === Type.GHOST);
}, Stat.SPD, 1)
.attr(PostIntimidateStatStageChangeAbAttr, [Stat.SPD], 1), .attr(PostIntimidateStatStageChangeAbAttr, [Stat.SPD], 1),
new Ability(Abilities.MAGIC_BOUNCE, 5) new Ability(Abilities.MAGIC_BOUNCE, 5)
.ignorable() .ignorable()
@ -5313,7 +5307,7 @@ export function initAbilities() {
.attr(UnsuppressableAbilityAbAttr) .attr(UnsuppressableAbilityAbAttr)
.attr(NoFusionAbilityAbAttr), .attr(NoFusionAbilityAbAttr),
new Ability(Abilities.GALE_WINGS, 6) new Ability(Abilities.GALE_WINGS, 6)
.attr(ChangeMovePriorityAbAttr, (pokemon, move) => pokemon.isFullHp() && move.type === Type.FLYING, 1), .attr(ChangeMovePriorityAbAttr, (pokemon, move) => pokemon.isFullHp() && pokemon.getMoveType(move) === Type.FLYING, 1),
new Ability(Abilities.MEGA_LAUNCHER, 6) new Ability(Abilities.MEGA_LAUNCHER, 6)
.attr(MovePowerBoostAbAttr, (user, target, move) => move.hasFlag(MoveFlags.PULSE_MOVE), 1.5), .attr(MovePowerBoostAbAttr, (user, target, move) => move.hasFlag(MoveFlags.PULSE_MOVE), 1.5),
new Ability(Abilities.GRASS_PELT, 6) new Ability(Abilities.GRASS_PELT, 6)
@ -5339,8 +5333,10 @@ export function initAbilities() {
.attr(FieldMoveTypePowerBoostAbAttr, Type.FAIRY, 4 / 3), .attr(FieldMoveTypePowerBoostAbAttr, Type.FAIRY, 4 / 3),
new Ability(Abilities.AURA_BREAK, 6) new Ability(Abilities.AURA_BREAK, 6)
.ignorable() .ignorable()
.conditionalAttr(target => target.hasAbility(Abilities.DARK_AURA), FieldMoveTypePowerBoostAbAttr, Type.DARK, 9 / 16) .conditionalAttr(pokemon => pokemon.scene.getField(true).some(p => p.hasAbility(Abilities.DARK_AURA)), FieldMoveTypePowerBoostAbAttr, Type.DARK, 9 / 16)
.conditionalAttr(target => target.hasAbility(Abilities.FAIRY_AURA), FieldMoveTypePowerBoostAbAttr, Type.FAIRY, 9 / 16), .conditionalAttr(pokemon => pokemon.scene.getField(true).some(p => p.hasAbility(Abilities.FAIRY_AURA)), FieldMoveTypePowerBoostAbAttr, Type.FAIRY, 9 / 16)
.conditionalAttr(pokemon => pokemon.scene.getField(true).some(p => p.hasAbility(Abilities.DARK_AURA) || p.hasAbility(Abilities.FAIRY_AURA)),
PostSummonMessageAbAttr, (pokemon: Pokemon) => i18next.t("abilityTriggers:postSummonAuraBreak", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon) })),
new Ability(Abilities.PRIMORDIAL_SEA, 6) new Ability(Abilities.PRIMORDIAL_SEA, 6)
.attr(PostSummonWeatherChangeAbAttr, WeatherType.HEAVY_RAIN) .attr(PostSummonWeatherChangeAbAttr, WeatherType.HEAVY_RAIN)
.attr(PostBiomeChangeWeatherChangeAbAttr, WeatherType.HEAVY_RAIN) .attr(PostBiomeChangeWeatherChangeAbAttr, WeatherType.HEAVY_RAIN)
@ -5368,7 +5364,7 @@ export function initAbilities() {
.condition(getSheerForceHitDisableAbCondition()) .condition(getSheerForceHitDisableAbCondition())
.unimplemented(), .unimplemented(),
new Ability(Abilities.WATER_COMPACTION, 7) new Ability(Abilities.WATER_COMPACTION, 7)
.attr(PostDefendStatStageChangeAbAttr, (target, user, move) => move.type === Type.WATER && move.category !== MoveCategory.STATUS, Stat.DEF, 2), .attr(PostDefendStatStageChangeAbAttr, (target, user, move) => user.getMoveType(move) === Type.WATER && move.category !== MoveCategory.STATUS, Stat.DEF, 2),
new Ability(Abilities.MERCILESS, 7) new Ability(Abilities.MERCILESS, 7)
.attr(ConditionalCritAbAttr, (user, target, move) => target?.status?.effect === StatusEffect.TOXIC || target?.status?.effect === StatusEffect.POISON), .attr(ConditionalCritAbAttr, (user, target, move) => target?.status?.effect === StatusEffect.TOXIC || target?.status?.effect === StatusEffect.POISON),
new Ability(Abilities.SHIELDS_DOWN, 7) new Ability(Abilities.SHIELDS_DOWN, 7)
@ -5424,7 +5420,7 @@ export function initAbilities() {
.attr(NoFusionAbilityAbAttr) .attr(NoFusionAbilityAbAttr)
// Add BattlerTagType.DISGUISE if the pokemon is in its disguised form // Add BattlerTagType.DISGUISE if the pokemon is in its disguised form
.conditionalAttr(pokemon => pokemon.formIndex === 0, PostSummonAddBattlerTagAbAttr, BattlerTagType.DISGUISE, 0, false) .conditionalAttr(pokemon => pokemon.formIndex === 0, PostSummonAddBattlerTagAbAttr, BattlerTagType.DISGUISE, 0, false)
.attr(FormBlockDamageAbAttr, (target, user, move) => !!target.getTag(BattlerTagType.DISGUISE) && target.getAttackTypeEffectiveness(move.type, user) > 0, 0, BattlerTagType.DISGUISE, .attr(FormBlockDamageAbAttr, (target, user, move) => !!target.getTag(BattlerTagType.DISGUISE) && target.getMoveEffectiveness(user, move) > 0, 0, BattlerTagType.DISGUISE,
(pokemon, abilityName) => i18next.t("abilityTriggers:disguiseAvoidedDamage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName: abilityName }), (pokemon, abilityName) => i18next.t("abilityTriggers:disguiseAvoidedDamage", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), abilityName: abilityName }),
(pokemon) => Utils.toDmgValue(pokemon.getMaxHp() / 8)) (pokemon) => Utils.toDmgValue(pokemon.getMaxHp() / 8))
.attr(PostBattleInitFormChangeAbAttr, () => 0) .attr(PostBattleInitFormChangeAbAttr, () => 0)
@ -5469,7 +5465,7 @@ export function initAbilities() {
.attr(AllyMoveCategoryPowerBoostAbAttr, [MoveCategory.SPECIAL], 1.3), .attr(AllyMoveCategoryPowerBoostAbAttr, [MoveCategory.SPECIAL], 1.3),
new Ability(Abilities.FLUFFY, 7) new Ability(Abilities.FLUFFY, 7)
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => move.hasFlag(MoveFlags.MAKES_CONTACT), 0.5) .attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => move.hasFlag(MoveFlags.MAKES_CONTACT), 0.5)
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => move.type === Type.FIRE, 2) .attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => user.getMoveType(move) === Type.FIRE, 2)
.ignorable(), .ignorable(),
new Ability(Abilities.DAZZLING, 7) new Ability(Abilities.DAZZLING, 7)
.attr(FieldPriorityMoveImmunityAbAttr) .attr(FieldPriorityMoveImmunityAbAttr)
@ -5519,10 +5515,10 @@ export function initAbilities() {
new Ability(Abilities.SHADOW_SHIELD, 7) new Ability(Abilities.SHADOW_SHIELD, 7)
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => target.isFullHp(), 0.5), .attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => target.isFullHp(), 0.5),
new Ability(Abilities.PRISM_ARMOR, 7) new Ability(Abilities.PRISM_ARMOR, 7)
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => target.getAttackTypeEffectiveness(move.type, user) >= 2, 0.75), .attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => target.getMoveEffectiveness(user, move) >= 2, 0.75),
new Ability(Abilities.NEUROFORCE, 7) new Ability(Abilities.NEUROFORCE, 7)
//@ts-ignore //@ts-ignore
.attr(MovePowerBoostAbAttr, (user, target, move) => target.getAttackTypeEffectiveness(move.type, user) >= 2, 1.25), // TODO: fix TS issues .attr(MovePowerBoostAbAttr, (user, target, move) => target?.getMoveEffectiveness(user, move) >= 2, 1.25), // TODO: fix TS issues
new Ability(Abilities.INTREPID_SWORD, 8) new Ability(Abilities.INTREPID_SWORD, 8)
.attr(PostSummonStatStageChangeAbAttr, [ Stat.ATK ], 1, true) .attr(PostSummonStatStageChangeAbAttr, [ Stat.ATK ], 1, true)
.condition(getOncePerBattleCondition(Abilities.INTREPID_SWORD)), .condition(getOncePerBattleCondition(Abilities.INTREPID_SWORD)),
@ -5553,7 +5549,11 @@ export function initAbilities() {
new Ability(Abilities.STALWART, 8) new Ability(Abilities.STALWART, 8)
.attr(BlockRedirectAbAttr), .attr(BlockRedirectAbAttr),
new Ability(Abilities.STEAM_ENGINE, 8) new Ability(Abilities.STEAM_ENGINE, 8)
.attr(PostDefendStatStageChangeAbAttr, (target, user, move) => (move.type === Type.FIRE || move.type === Type.WATER) && move.category !== MoveCategory.STATUS, Stat.SPD, 6), .attr(PostDefendStatStageChangeAbAttr, (target, user, move) => {
const moveType = user.getMoveType(move);
return move.category !== MoveCategory.STATUS
&& (moveType === Type.FIRE || moveType === Type.WATER);
}, Stat.SPD, 6),
new Ability(Abilities.PUNK_ROCK, 8) new Ability(Abilities.PUNK_ROCK, 8)
.attr(MovePowerBoostAbAttr, (user, target, move) => move.hasFlag(MoveFlags.SOUND_BASED), 1.3) .attr(MovePowerBoostAbAttr, (user, target, move) => move.hasFlag(MoveFlags.SOUND_BASED), 1.3)
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => move.hasFlag(MoveFlags.SOUND_BASED), 0.5) .attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => move.hasFlag(MoveFlags.SOUND_BASED), 0.5)
@ -5653,7 +5653,7 @@ export function initAbilities() {
new Ability(Abilities.SEED_SOWER, 9) new Ability(Abilities.SEED_SOWER, 9)
.attr(PostDefendTerrainChangeAbAttr, TerrainType.GRASSY), .attr(PostDefendTerrainChangeAbAttr, TerrainType.GRASSY),
new Ability(Abilities.THERMAL_EXCHANGE, 9) new Ability(Abilities.THERMAL_EXCHANGE, 9)
.attr(PostDefendStatStageChangeAbAttr, (target, user, move) => move.type === Type.FIRE && move.category !== MoveCategory.STATUS, Stat.ATK, 1) .attr(PostDefendStatStageChangeAbAttr, (target, user, move) => user.getMoveType(move) === Type.FIRE && move.category !== MoveCategory.STATUS, Stat.ATK, 1)
.attr(StatusEffectImmunityAbAttr, StatusEffect.BURN) .attr(StatusEffectImmunityAbAttr, StatusEffect.BURN)
.ignorable(), .ignorable(),
new Ability(Abilities.ANGER_SHELL, 9) new Ability(Abilities.ANGER_SHELL, 9)

View File

@ -39,13 +39,15 @@ export class BattlerTag {
public turnCount: number; public turnCount: number;
public sourceMove: Moves; public sourceMove: Moves;
public sourceId?: number; public sourceId?: number;
public isBatonPassable: boolean;
constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType | BattlerTagLapseType[], turnCount: number, sourceMove?: Moves, sourceId?: number) { constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType | BattlerTagLapseType[], turnCount: number, sourceMove?: Moves, sourceId?: number, isBatonPassable: boolean = false) {
this.tagType = tagType; this.tagType = tagType;
this.lapseTypes = Array.isArray(lapseType) ? lapseType : [ lapseType ]; this.lapseTypes = Array.isArray(lapseType) ? lapseType : [ lapseType ];
this.turnCount = turnCount; this.turnCount = turnCount;
this.sourceMove = sourceMove!; // TODO: is this bang correct? this.sourceMove = sourceMove!; // TODO: is this bang correct?
this.sourceId = sourceId; this.sourceId = sourceId;
this.isBatonPassable = isBatonPassable;
} }
canAdd(pokemon: Pokemon): boolean { canAdd(pokemon: Pokemon): boolean {
@ -96,6 +98,127 @@ export interface TerrainBattlerTag {
terrainTypes: TerrainType[]; terrainTypes: TerrainType[];
} }
/**
* Base class for tags that restrict the usage of moves. This effect is generally referred to as "disabling" a move
* in-game. This is not to be confused with {@linkcode Moves.DISABLE}.
*
* Descendants can override {@linkcode isMoveRestricted} to restrict moves that
* match a condition. A restricted move gets cancelled before it is used. Players and enemies should not be allowed
* to select restricted moves.
*/
export abstract class MoveRestrictionBattlerTag extends BattlerTag {
constructor(tagType: BattlerTagType, turnCount: integer, sourceMove?: Moves, sourceId?: integer) {
super(tagType, [ BattlerTagLapseType.PRE_MOVE, BattlerTagLapseType.TURN_END ], turnCount, sourceMove, sourceId);
}
/** @override */
override lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
if (lapseType === BattlerTagLapseType.PRE_MOVE) {
// Cancel the affected pokemon's selected move
const phase = pokemon.scene.getCurrentPhase() as MovePhase;
const move = phase.move;
if (this.isMoveRestricted(move.moveId)) {
pokemon.scene.queueMessage(this.interruptedText(pokemon, move.moveId));
phase.cancel();
}
return true;
}
return super.lapse(pokemon, lapseType);
}
/**
* Gets whether this tag is restricting a move.
*
* @param {Moves} move {@linkcode Moves} ID to check restriction for.
* @returns {boolean} `true` if the move is restricted by this tag, otherwise `false`.
*/
abstract isMoveRestricted(move: Moves): boolean;
/**
* Gets the text to display when the player attempts to select a move that is restricted by this tag.
*
* @param {Pokemon} pokemon {@linkcode Pokemon} for which the player is attempting to select the restricted move
* @param {Moves} move {@linkcode Moves} ID of the move that is having its selection denied
* @returns {string} text to display when the player attempts to select the restricted move
*/
abstract selectionDeniedText(pokemon: Pokemon, move: Moves): string;
/**
* Gets the text to display when a move's execution is prevented as a result of the restriction.
* Because restriction effects also prevent selection of the move, this situation can only arise if a
* pokemon first selects a move, then gets outsped by a pokemon using a move that restricts the selected move.
*
* @param {Pokemon} pokemon {@linkcode Pokemon} attempting to use the restricted move
* @param {Moves} move {@linkcode Moves} ID of the move being interrupted
* @returns {string} text to display when the move is interrupted
*/
abstract interruptedText(pokemon: Pokemon, move: Moves): string;
}
/**
* Tag representing the "disabling" effect performed by {@linkcode Moves.DISABLE} and {@linkcode Abilities.CURSED_BODY}.
* When the tag is added, the last-used move of the tag holder is set as the disabled move.
*/
export class DisabledTag extends MoveRestrictionBattlerTag {
/** The move being disabled. Gets set when {@linkcode onAdd} is called for this tag. */
private moveId: Moves = Moves.NONE;
constructor(sourceId: number) {
super(BattlerTagType.DISABLED, 4, Moves.DISABLE, sourceId);
}
/** @override */
override isMoveRestricted(move: Moves): boolean {
return move === this.moveId;
}
/**
* @override
*
* Ensures that move history exists on `pokemon` and has a valid move. If so, sets the {@link moveId} and shows a message.
* Otherwise the move ID will not get assigned and this tag will get removed next turn.
*/
override onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon);
const move = pokemon.getLastXMoves()
.find(m => m.move !== Moves.NONE && m.move !== Moves.STRUGGLE && !m.virtual);
if (move === undefined) {
return;
}
this.moveId = move.move;
pokemon.scene.queueMessage(i18next.t("battlerTags:disabledOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[this.moveId].name }));
}
/** @override */
override onRemove(pokemon: Pokemon): void {
super.onRemove(pokemon);
pokemon.scene.queueMessage(i18next.t("battlerTags:disabledLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[this.moveId].name }));
}
/** @override */
override selectionDeniedText(pokemon: Pokemon, move: Moves): string {
return i18next.t("battle:moveDisabled", { moveName: allMoves[move].name });
}
/** @override */
override interruptedText(pokemon: Pokemon, move: Moves): string {
return i18next.t("battle:disableInterruptedMove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name });
}
/** @override */
override loadTag(source: BattlerTag | any): void {
super.loadTag(source);
this.moveId = source.moveId;
}
}
/** /**
* BattlerTag that represents the "recharge" effects of moves like Hyper Beam. * BattlerTag that represents the "recharge" effects of moves like Hyper Beam.
*/ */
@ -206,7 +329,7 @@ export class ShellTrapTag extends BattlerTag {
export class TrappedTag extends BattlerTag { export class TrappedTag extends BattlerTag {
constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType, turnCount: number, sourceMove: Moves, sourceId: number) { constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType, turnCount: number, sourceMove: Moves, sourceId: number) {
super(tagType, lapseType, turnCount, sourceMove, sourceId); super(tagType, lapseType, turnCount, sourceMove, sourceId, true);
} }
canAdd(pokemon: Pokemon): boolean { canAdd(pokemon: Pokemon): boolean {
@ -326,7 +449,7 @@ export class InterruptedTag extends BattlerTag {
*/ */
export class ConfusedTag extends BattlerTag { export class ConfusedTag extends BattlerTag {
constructor(turnCount: number, sourceMove: Moves) { constructor(turnCount: number, sourceMove: Moves) {
super(BattlerTagType.CONFUSED, BattlerTagLapseType.MOVE, turnCount, sourceMove); super(BattlerTagType.CONFUSED, BattlerTagLapseType.MOVE, turnCount, sourceMove, undefined, true);
} }
canAdd(pokemon: Pokemon): boolean { canAdd(pokemon: Pokemon): boolean {
@ -363,7 +486,7 @@ export class ConfusedTag extends BattlerTag {
if (pokemon.randSeedInt(3) === 0) { if (pokemon.randSeedInt(3) === 0) {
const atk = pokemon.getEffectiveStat(Stat.ATK); const atk = pokemon.getEffectiveStat(Stat.ATK);
const def = pokemon.getEffectiveStat(Stat.DEF); const def = pokemon.getEffectiveStat(Stat.DEF);
const damage = Utils.toDmgValue(((((2 * pokemon.level / 5 + 2) * 40 * atk / def) / 50) + 2) * (pokemon.randSeedInt(15, 85) / 100)); const damage = Utils.toDmgValue(((((2 * pokemon.level / 5 + 2) * 40 * atk / def) / 50) + 2) * (pokemon.randSeedIntRange(85, 100) / 100));
pokemon.scene.queueMessage(i18next.t("battlerTags:confusedLapseHurtItself")); pokemon.scene.queueMessage(i18next.t("battlerTags:confusedLapseHurtItself"));
pokemon.damageAndUpdate(damage); pokemon.damageAndUpdate(damage);
pokemon.battleData.hitCount++; pokemon.battleData.hitCount++;
@ -386,7 +509,7 @@ export class ConfusedTag extends BattlerTag {
*/ */
export class DestinyBondTag extends BattlerTag { export class DestinyBondTag extends BattlerTag {
constructor(sourceMove: Moves, sourceId: number) { constructor(sourceMove: Moves, sourceId: number) {
super(BattlerTagType.DESTINY_BOND, BattlerTagLapseType.PRE_MOVE, 1, sourceMove, sourceId); super(BattlerTagType.DESTINY_BOND, BattlerTagLapseType.PRE_MOVE, 1, sourceMove, sourceId, true);
} }
/** /**
@ -505,7 +628,7 @@ export class SeedTag extends BattlerTag {
private sourceIndex: number; private sourceIndex: number;
constructor(sourceId: number) { constructor(sourceId: number) {
super(BattlerTagType.SEEDED, BattlerTagLapseType.TURN_END, 1, Moves.LEECH_SEED, sourceId); super(BattlerTagType.SEEDED, BattlerTagLapseType.TURN_END, 1, Moves.LEECH_SEED, sourceId, true);
} }
/** /**
@ -776,7 +899,7 @@ export class OctolockTag extends TrappedTag {
export class AquaRingTag extends BattlerTag { export class AquaRingTag extends BattlerTag {
constructor() { constructor() {
super(BattlerTagType.AQUA_RING, BattlerTagLapseType.TURN_END, 1, Moves.AQUA_RING, undefined); super(BattlerTagType.AQUA_RING, BattlerTagLapseType.TURN_END, 1, Moves.AQUA_RING, undefined, true);
} }
onAdd(pokemon: Pokemon): void { onAdd(pokemon: Pokemon): void {
@ -808,7 +931,7 @@ export class AquaRingTag extends BattlerTag {
/** Tag used to allow moves that interact with {@link Moves.MINIMIZE} to function */ /** Tag used to allow moves that interact with {@link Moves.MINIMIZE} to function */
export class MinimizeTag extends BattlerTag { export class MinimizeTag extends BattlerTag {
constructor() { constructor() {
super(BattlerTagType.MINIMIZED, BattlerTagLapseType.TURN_END, 1, Moves.MINIMIZE, undefined); super(BattlerTagType.MINIMIZED, BattlerTagLapseType.TURN_END, 1, Moves.MINIMIZE);
} }
canAdd(pokemon: Pokemon): boolean { canAdd(pokemon: Pokemon): boolean {
@ -1206,7 +1329,7 @@ export class SturdyTag extends BattlerTag {
export class PerishSongTag extends BattlerTag { export class PerishSongTag extends BattlerTag {
constructor(turnCount: number) { constructor(turnCount: number) {
super(BattlerTagType.PERISH_SONG, BattlerTagLapseType.TURN_END, turnCount, Moves.PERISH_SONG); super(BattlerTagType.PERISH_SONG, BattlerTagLapseType.TURN_END, turnCount, Moves.PERISH_SONG, undefined, true);
} }
canAdd(pokemon: Pokemon): boolean { canAdd(pokemon: Pokemon): boolean {
@ -1262,7 +1385,7 @@ export class AbilityBattlerTag extends BattlerTag {
public ability: Abilities; public ability: Abilities;
constructor(tagType: BattlerTagType, ability: Abilities, lapseType: BattlerTagLapseType, turnCount: number) { constructor(tagType: BattlerTagType, ability: Abilities, lapseType: BattlerTagLapseType, turnCount: number) {
super(tagType, lapseType, turnCount, undefined); super(tagType, lapseType, turnCount);
this.ability = ability; this.ability = ability;
} }
@ -1438,7 +1561,7 @@ export class TypeImmuneTag extends BattlerTag {
public immuneType: Type; public immuneType: Type;
constructor(tagType: BattlerTagType, sourceMove: Moves, immuneType: Type, length: number = 1) { constructor(tagType: BattlerTagType, sourceMove: Moves, immuneType: Type, length: number = 1) {
super(tagType, BattlerTagLapseType.TURN_END, length, sourceMove); super(tagType, BattlerTagLapseType.TURN_END, length, sourceMove, undefined, true);
this.immuneType = immuneType; this.immuneType = immuneType;
} }
@ -1502,7 +1625,7 @@ export class TypeBoostTag extends BattlerTag {
export class CritBoostTag extends BattlerTag { export class CritBoostTag extends BattlerTag {
constructor(tagType: BattlerTagType, sourceMove: Moves) { constructor(tagType: BattlerTagType, sourceMove: Moves) {
super(tagType, BattlerTagLapseType.TURN_END, 1, sourceMove); super(tagType, BattlerTagLapseType.TURN_END, 1, sourceMove, undefined, true);
} }
onAdd(pokemon: Pokemon): void { onAdd(pokemon: Pokemon): void {
@ -1594,7 +1717,7 @@ export class CursedTag extends BattlerTag {
private sourceIndex: number; private sourceIndex: number;
constructor(sourceId: number) { constructor(sourceId: number) {
super(BattlerTagType.CURSED, BattlerTagLapseType.TURN_END, 1, Moves.CURSE, sourceId); super(BattlerTagType.CURSED, BattlerTagLapseType.TURN_END, 1, Moves.CURSE, sourceId, true);
} }
/** /**
@ -1993,6 +2116,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source
return new StockpilingTag(sourceMove); return new StockpilingTag(sourceMove);
case BattlerTagType.OCTOLOCK: case BattlerTagType.OCTOLOCK:
return new OctolockTag(sourceId); return new OctolockTag(sourceId);
case BattlerTagType.DISABLED:
return new DisabledTag(sourceId);
case BattlerTagType.IGNORE_GHOST: case BattlerTagType.IGNORE_GHOST:
return new ExposedTag(tagType, sourceMove, Type.GHOST, [Type.NORMAL, Type.FIGHTING]); return new ExposedTag(tagType, sourceMove, Type.GHOST, [Type.NORMAL, Type.FIGHTING]);
case BattlerTagType.IGNORE_DARK: case BattlerTagType.IGNORE_DARK:

View File

@ -1,18 +1,18 @@
import * as Utils from "../utils"; import * as Utils from "../utils";
import i18next from "i18next"; import i18next from "i18next";
import { defaultStarterSpecies, DexAttrProps, GameData } from "#app/system/game-data.js"; import { defaultStarterSpecies, DexAttrProps, GameData } from "#app/system/game-data";
import PokemonSpecies, { getPokemonSpecies, getPokemonSpeciesForm, speciesStarters } from "./pokemon-species"; import PokemonSpecies, { getPokemonSpecies, getPokemonSpeciesForm, speciesStarters } from "./pokemon-species";
import Pokemon, { PokemonMove } from "#app/field/pokemon.js"; import Pokemon, { PokemonMove } from "#app/field/pokemon";
import { BattleType, FixedBattleConfig } from "#app/battle.js"; import { BattleType, FixedBattleConfig } from "#app/battle";
import Trainer, { TrainerVariant } from "#app/field/trainer.js"; import Trainer, { TrainerVariant } from "#app/field/trainer";
import { GameMode } from "#app/game-mode.js"; import { GameMode } from "#app/game-mode";
import { Type } from "./type"; import { Type } from "./type";
import { Challenges } from "#enums/challenges"; import { Challenges } from "#enums/challenges";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { TrainerType } from "#enums/trainer-type"; import { TrainerType } from "#enums/trainer-type";
import { Nature } from "./nature"; import { Nature } from "./nature";
import { Moves } from "#app/enums/moves.js"; import { Moves } from "#app/enums/moves";
import { TypeColor, TypeShadow } from "#app/enums/color.js"; import { TypeColor, TypeShadow } from "#app/enums/color";
import { pokemonEvolutions } from "./pokemon-evolutions"; import { pokemonEvolutions } from "./pokemon-evolutions";
import { pokemonFormChanges } from "./pokemon-forms"; import { pokemonFormChanges } from "./pokemon-forms";

View File

@ -0,0 +1,98 @@
import BattleScene from "#app/battle-scene";
import { PlayerPokemon } from "#app/field/pokemon";
import { DexEntry, StarterDataEntry } from "#app/system/game-data";
/**
* Stores data associated with a specific egg and the hatched pokemon
* Allows hatch info to be stored at hatch then retrieved for display during egg summary
*/
export class EggHatchData {
/** the pokemon that hatched from the file (including shiny, IVs, ability) */
public pokemon: PlayerPokemon;
/** index of the egg move from the hatched pokemon (not stored in PlayerPokemon) */
public eggMoveIndex: number;
/** boolean indicating if the egg move for the hatch is new */
public eggMoveUnlocked: boolean;
/** stored copy of the hatched pokemon's dex entry before it was updated due to hatch */
public dexEntryBeforeUpdate: DexEntry;
/** stored copy of the hatched pokemon's starter entry before it was updated due to hatch */
public starterDataEntryBeforeUpdate: StarterDataEntry;
/** reference to the battle scene to get gamedata and update dex */
private scene: BattleScene;
constructor(scene: BattleScene, pokemon: PlayerPokemon, eggMoveIndex: number) {
this.scene = scene;
this.pokemon = pokemon;
this.eggMoveIndex = eggMoveIndex;
}
/**
* Sets the boolean for if the egg move for the hatch is a new unlock
* @param unlocked True if the EM is new
*/
setEggMoveUnlocked(unlocked: boolean) {
this.eggMoveUnlocked = unlocked;
}
/**
* Stores a copy of the current DexEntry of the pokemon and StarterDataEntry of its starter
* Used before updating the dex, so comparing the pokemon to these entries will show the new attributes
*/
setDex() {
const currDexEntry = this.scene.gameData.dexData[this.pokemon.species.speciesId];
const currStarterDataEntry = this.scene.gameData.starterData[this.pokemon.species.getRootSpeciesId()];
this.dexEntryBeforeUpdate = {
seenAttr: currDexEntry.seenAttr,
caughtAttr: currDexEntry.caughtAttr,
natureAttr: currDexEntry.natureAttr,
seenCount: currDexEntry.seenCount,
caughtCount: currDexEntry.caughtCount,
hatchedCount: currDexEntry.hatchedCount,
ivs: [...currDexEntry.ivs]
};
this.starterDataEntryBeforeUpdate = {
moveset: currStarterDataEntry.moveset,
eggMoves: currStarterDataEntry.eggMoves,
candyCount: currStarterDataEntry.candyCount,
friendship: currStarterDataEntry.friendship,
abilityAttr: currStarterDataEntry.abilityAttr,
passiveAttr: currStarterDataEntry.passiveAttr,
valueReduction: currStarterDataEntry.valueReduction,
classicWinCount: currStarterDataEntry.classicWinCount
};
}
/**
* Gets the dex entry before update
* @returns Dex Entry corresponding to this pokemon before the pokemon was added / updated to dex
*/
getDex(): DexEntry {
return this.dexEntryBeforeUpdate;
}
/**
* Gets the starter dex entry before update
* @returns Starter Dex Entry corresponding to this pokemon before the pokemon was added / updated to dex
*/
getStarterEntry(): StarterDataEntry {
return this.starterDataEntryBeforeUpdate;
}
/**
* Update the pokedex data corresponding with the new hatch's pokemon data
* Also sets whether the egg move is a new unlock or not
* @param showMessage boolean to show messages for the new catches and egg moves (false by default)
* @returns
*/
updatePokemon(showMessage : boolean = false) {
return new Promise<void>(resolve => {
this.scene.gameData.setPokemonCaught(this.pokemon, true, true, showMessage).then(() => {
this.scene.gameData.updateSpeciesDexIvs(this.pokemon.species.speciesId, this.pokemon.ivs);
this.scene.gameData.setEggMoveUnlocked(this.pokemon.species, this.eggMoveIndex, showMessage).then((value) => {
this.setEggMoveUnlocked(value);
resolve();
});
});
});
}
}

View File

@ -8,14 +8,14 @@ import { PlayerPokemon } from "#app/field/pokemon";
import i18next from "i18next"; import i18next from "i18next";
import { EggTier } from "#enums/egg-type"; import { EggTier } from "#enums/egg-type";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { EggSourceType } from "#app/enums/egg-source-types.js"; import { EggSourceType } from "#app/enums/egg-source-types";
export const EGG_SEED = 1073741824; export const EGG_SEED = 1073741824;
// Rates for specific random properties in 1/x // Rates for specific random properties in 1/x
const DEFAULT_SHINY_RATE = 128; const DEFAULT_SHINY_RATE = 128;
const GACHA_SHINY_UP_SHINY_RATE = 64; const GACHA_SHINY_UP_SHINY_RATE = 64;
const SAME_SPECIES_EGG_SHINY_RATE = 24; const SAME_SPECIES_EGG_SHINY_RATE = 12;
const SAME_SPECIES_EGG_HA_RATE = 8; const SAME_SPECIES_EGG_HA_RATE = 8;
const MANAPHY_EGG_MANAPHY_RATE = 8; const MANAPHY_EGG_MANAPHY_RATE = 8;
const GACHA_EGG_HA_RATE = 192; const GACHA_EGG_HA_RATE = 192;

View File

@ -757,12 +757,14 @@ export default class Move implements Localizable {
const fieldAuras = new Set( const fieldAuras = new Set(
source.scene.getField(true) source.scene.getField(true)
.map((p) => p.getAbilityAttrs(FieldMoveTypePowerBoostAbAttr) as FieldMoveTypePowerBoostAbAttr[]) .map((p) => p.getAbilityAttrs(FieldMoveTypePowerBoostAbAttr).filter(attr => {
const condition = attr.getCondition();
return (!condition || condition(p));
}) as FieldMoveTypePowerBoostAbAttr[])
.flat(), .flat(),
); );
for (const aura of fieldAuras) { for (const aura of fieldAuras) {
// The only relevant values are `move` and the `power` holder aura.applyPreAttack(source, null, simulated, target, this, [power]);
aura.applyPreAttack(null, null, simulated, null, this, [power]);
} }
const alliedField: Pokemon[] = source instanceof PlayerPokemon ? source.scene.getPlayerField() : source.scene.getEnemyField(); const alliedField: Pokemon[] = source instanceof PlayerPokemon ? source.scene.getPlayerField() : source.scene.getEnemyField();
@ -4333,72 +4335,6 @@ export class TypelessAttr extends MoveAttr { }
*/ */
export class BypassRedirectAttr extends MoveAttr { } export class BypassRedirectAttr extends MoveAttr { }
export class DisableMoveAttr extends MoveEffectAttr {
constructor() {
super(false);
}
apply(user: Pokemon, target: Pokemon, move: Move, args: any[]): boolean {
if (!super.apply(user, target, move, args)) {
return false;
}
const moveQueue = target.getLastXMoves();
let turnMove: TurnMove | undefined;
while (moveQueue.length) {
turnMove = moveQueue.shift();
if (turnMove?.virtual) {
continue;
}
const moveIndex = target.getMoveset().findIndex(m => m?.moveId === turnMove?.move);
if (moveIndex === -1) {
return false;
}
const disabledMove = target.getMoveset()[moveIndex];
target.summonData.disabledMove = disabledMove?.moveId!; // TODO: is this bang correct?
target.summonData.disabledTurns = 4;
user.scene.queueMessage(i18next.t("abilityTriggers:postDefendMoveDisable", { pokemonNameWithAffix: getPokemonNameWithAffix(target), moveName: disabledMove?.getName()}));
return true;
}
return false;
}
getCondition(): MoveConditionFunc {
return (user, target, move): boolean => { // TODO: Not sure what to do here
if (target.summonData.disabledMove || target.isMax()) {
return false;
}
const moveQueue = target.getLastXMoves();
let turnMove: TurnMove | undefined;
while (moveQueue.length) {
turnMove = moveQueue.shift();
if (turnMove?.virtual) {
continue;
}
const move = target.getMoveset().find(m => m?.moveId === turnMove?.move);
if (!move) {
continue;
}
return true;
}
return false;
};
}
getTargetBenefitScore(user: Pokemon, target: Pokemon, move: Move): integer {
return -5;
}
}
export class FrenzyAttr extends MoveEffectAttr { export class FrenzyAttr extends MoveEffectAttr {
constructor() { constructor() {
super(true, MoveEffectTrigger.HIT, false, true); super(true, MoveEffectTrigger.HIT, false, true);
@ -4467,7 +4403,7 @@ export class AddBattlerTagAttr extends MoveEffectAttr {
const moveChance = this.getMoveChance(user, target, move, this.selfTarget, true); const moveChance = this.getMoveChance(user, target, move, this.selfTarget, true);
if (moveChance < 0 || moveChance === 100 || user.randSeedInt(100) < moveChance) { if (moveChance < 0 || moveChance === 100 || user.randSeedInt(100) < moveChance) {
return (this.selfTarget ? user : target).addTag(this.tagType, user.randSeedInt(this.turnCountMax - this.turnCountMin, this.turnCountMin), move.id, user.id); return (this.selfTarget ? user : target).addTag(this.tagType, user.randSeedIntRange(this.turnCountMin, this.turnCountMax), move.id, user.id);
} }
return false; return false;
@ -4489,6 +4425,7 @@ export class AddBattlerTagAttr extends MoveEffectAttr {
case BattlerTagType.INFATUATED: case BattlerTagType.INFATUATED:
case BattlerTagType.NIGHTMARE: case BattlerTagType.NIGHTMARE:
case BattlerTagType.DROWSY: case BattlerTagType.DROWSY:
case BattlerTagType.DISABLED:
return -5; return -5;
case BattlerTagType.SEEDED: case BattlerTagType.SEEDED:
case BattlerTagType.SALT_CURED: case BattlerTagType.SALT_CURED:
@ -6300,6 +6237,8 @@ const userSleptOrComatoseCondition: MoveConditionFunc = (user: Pokemon, target:
const targetSleptOrComatoseCondition: MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => target.status?.effect === StatusEffect.SLEEP || target.hasAbility(Abilities.COMATOSE); const targetSleptOrComatoseCondition: MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => target.status?.effect === StatusEffect.SLEEP || target.hasAbility(Abilities.COMATOSE);
const failIfLastCondition: MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => user.scene.phaseQueue.find(phase => phase instanceof MovePhase) !== undefined;
export type MoveAttrFilter = (attr: MoveAttr) => boolean; export type MoveAttrFilter = (attr: MoveAttr) => boolean;
function applyMoveAttrsInternal(attrFilter: MoveAttrFilter, user: Pokemon | null, target: Pokemon | null, move: Move, args: any[]): Promise<void> { function applyMoveAttrsInternal(attrFilter: MoveAttrFilter, user: Pokemon | null, target: Pokemon | null, move: Move, args: any[]): Promise<void> {
@ -6674,7 +6613,8 @@ export function initMoves() {
new AttackMove(Moves.SONIC_BOOM, Type.NORMAL, MoveCategory.SPECIAL, -1, 90, 20, -1, 0, 1) new AttackMove(Moves.SONIC_BOOM, Type.NORMAL, MoveCategory.SPECIAL, -1, 90, 20, -1, 0, 1)
.attr(FixedDamageAttr, 20), .attr(FixedDamageAttr, 20),
new StatusMove(Moves.DISABLE, Type.NORMAL, 100, 20, -1, 0, 1) new StatusMove(Moves.DISABLE, Type.NORMAL, 100, 20, -1, 0, 1)
.attr(DisableMoveAttr) .attr(AddBattlerTagAttr, BattlerTagType.DISABLED, false, true)
.condition((user, target, move) => target.getMoveHistory().reverse().find(m => m.move !== Moves.NONE && m.move !== Moves.STRUGGLE && !m.virtual) !== undefined)
.condition(failOnMaxCondition), .condition(failOnMaxCondition),
new AttackMove(Moves.ACID, Type.POISON, MoveCategory.SPECIAL, 40, 100, 30, 10, 0, 1) new AttackMove(Moves.ACID, Type.POISON, MoveCategory.SPECIAL, 40, 100, 30, 10, 0, 1)
.attr(StatStageChangeAttr, [ Stat.SPDEF ], -1) .attr(StatStageChangeAttr, [ Stat.SPDEF ], -1)
@ -7037,7 +6977,8 @@ export function initMoves() {
.attr(StatusEffectAttr, StatusEffect.FREEZE) .attr(StatusEffectAttr, StatusEffect.FREEZE)
.target(MoveTarget.ALL_NEAR_ENEMIES), .target(MoveTarget.ALL_NEAR_ENEMIES),
new SelfStatusMove(Moves.PROTECT, Type.NORMAL, -1, 10, -1, 4, 2) new SelfStatusMove(Moves.PROTECT, Type.NORMAL, -1, 10, -1, 4, 2)
.attr(ProtectAttr), .attr(ProtectAttr)
.condition(failIfLastCondition),
new AttackMove(Moves.MACH_PUNCH, Type.FIGHTING, MoveCategory.PHYSICAL, 40, 100, 30, -1, 1, 2) new AttackMove(Moves.MACH_PUNCH, Type.FIGHTING, MoveCategory.PHYSICAL, 40, 100, 30, -1, 1, 2)
.punchingMove(), .punchingMove(),
new StatusMove(Moves.SCARY_FACE, Type.NORMAL, 100, 10, -1, 0, 2) new StatusMove(Moves.SCARY_FACE, Type.NORMAL, 100, 10, -1, 0, 2)
@ -7088,7 +7029,8 @@ export function initMoves() {
.windMove() .windMove()
.target(MoveTarget.ALL_NEAR_ENEMIES), .target(MoveTarget.ALL_NEAR_ENEMIES),
new SelfStatusMove(Moves.DETECT, Type.FIGHTING, -1, 5, -1, 4, 2) new SelfStatusMove(Moves.DETECT, Type.FIGHTING, -1, 5, -1, 4, 2)
.attr(ProtectAttr), .attr(ProtectAttr)
.condition(failIfLastCondition),
new AttackMove(Moves.BONE_RUSH, Type.GROUND, MoveCategory.PHYSICAL, 25, 90, 10, -1, 0, 2) new AttackMove(Moves.BONE_RUSH, Type.GROUND, MoveCategory.PHYSICAL, 25, 90, 10, -1, 0, 2)
.attr(MultiHitAttr) .attr(MultiHitAttr)
.makesContact(false), .makesContact(false),
@ -7106,7 +7048,8 @@ export function initMoves() {
.attr(HitHealAttr) .attr(HitHealAttr)
.triageMove(), .triageMove(),
new SelfStatusMove(Moves.ENDURE, Type.NORMAL, -1, 10, -1, 4, 2) new SelfStatusMove(Moves.ENDURE, Type.NORMAL, -1, 10, -1, 4, 2)
.attr(ProtectAttr, BattlerTagType.ENDURING), .attr(ProtectAttr, BattlerTagType.ENDURING)
.condition(failIfLastCondition),
new StatusMove(Moves.CHARM, Type.FAIRY, 100, 20, -1, 0, 2) new StatusMove(Moves.CHARM, Type.FAIRY, 100, 20, -1, 0, 2)
.attr(StatStageChangeAttr, [ Stat.ATK ], -2), .attr(StatStageChangeAttr, [ Stat.ATK ], -2),
new AttackMove(Moves.ROLLOUT, Type.ROCK, MoveCategory.PHYSICAL, 30, 90, 20, -1, 0, 2) new AttackMove(Moves.ROLLOUT, Type.ROCK, MoveCategory.PHYSICAL, 30, 90, 20, -1, 0, 2)
@ -7853,7 +7796,8 @@ export function initMoves() {
.attr(StatStageChangeAttr, [ Stat.ATK, Stat.ACC ], 1, true), .attr(StatStageChangeAttr, [ Stat.ATK, Stat.ACC ], 1, true),
new StatusMove(Moves.WIDE_GUARD, Type.ROCK, -1, 10, -1, 3, 5) new StatusMove(Moves.WIDE_GUARD, Type.ROCK, -1, 10, -1, 3, 5)
.target(MoveTarget.USER_SIDE) .target(MoveTarget.USER_SIDE)
.attr(AddArenaTagAttr, ArenaTagType.WIDE_GUARD, 1, true, true), .attr(AddArenaTagAttr, ArenaTagType.WIDE_GUARD, 1, true, true)
.condition(failIfLastCondition),
new StatusMove(Moves.GUARD_SPLIT, Type.PSYCHIC, -1, 10, -1, 0, 5) new StatusMove(Moves.GUARD_SPLIT, Type.PSYCHIC, -1, 10, -1, 0, 5)
.attr(AverageStatsAttr, [ Stat.DEF, Stat.SPDEF ], "moveTriggers:sharedGuard"), .attr(AverageStatsAttr, [ Stat.DEF, Stat.SPDEF ], "moveTriggers:sharedGuard"),
new StatusMove(Moves.POWER_SPLIT, Type.PSYCHIC, -1, 10, -1, 0, 5) new StatusMove(Moves.POWER_SPLIT, Type.PSYCHIC, -1, 10, -1, 0, 5)
@ -7941,7 +7885,8 @@ export function initMoves() {
.attr(PositiveStatStagePowerAttr), .attr(PositiveStatStagePowerAttr),
new StatusMove(Moves.QUICK_GUARD, Type.FIGHTING, -1, 15, -1, 3, 5) new StatusMove(Moves.QUICK_GUARD, Type.FIGHTING, -1, 15, -1, 3, 5)
.target(MoveTarget.USER_SIDE) .target(MoveTarget.USER_SIDE)
.attr(AddArenaTagAttr, ArenaTagType.QUICK_GUARD, 1, true, true), .attr(AddArenaTagAttr, ArenaTagType.QUICK_GUARD, 1, true, true)
.condition(failIfLastCondition),
new SelfStatusMove(Moves.ALLY_SWITCH, Type.PSYCHIC, -1, 15, -1, 2, 5) new SelfStatusMove(Moves.ALLY_SWITCH, Type.PSYCHIC, -1, 15, -1, 2, 5)
.ignoresProtect() .ignoresProtect()
.unimplemented(), .unimplemented(),
@ -8112,7 +8057,8 @@ export function initMoves() {
new StatusMove(Moves.MAT_BLOCK, Type.FIGHTING, -1, 10, -1, 0, 6) new StatusMove(Moves.MAT_BLOCK, Type.FIGHTING, -1, 10, -1, 0, 6)
.target(MoveTarget.USER_SIDE) .target(MoveTarget.USER_SIDE)
.attr(AddArenaTagAttr, ArenaTagType.MAT_BLOCK, 1, true, true) .attr(AddArenaTagAttr, ArenaTagType.MAT_BLOCK, 1, true, true)
.condition(new FirstMoveCondition()), .condition(new FirstMoveCondition())
.condition(failIfLastCondition),
new AttackMove(Moves.BELCH, Type.POISON, MoveCategory.SPECIAL, 120, 90, 10, -1, 0, 6) new AttackMove(Moves.BELCH, Type.POISON, MoveCategory.SPECIAL, 120, 90, 10, -1, 0, 6)
.condition((user, target, move) => user.battleData.berriesEaten.length > 0), .condition((user, target, move) => user.battleData.berriesEaten.length > 0),
new StatusMove(Moves.ROTOTILLER, Type.GROUND, -1, 10, -1, 0, 6) new StatusMove(Moves.ROTOTILLER, Type.GROUND, -1, 10, -1, 0, 6)
@ -8170,7 +8116,8 @@ export function initMoves() {
.triageMove(), .triageMove(),
new StatusMove(Moves.CRAFTY_SHIELD, Type.FAIRY, -1, 10, -1, 3, 6) new StatusMove(Moves.CRAFTY_SHIELD, Type.FAIRY, -1, 10, -1, 3, 6)
.target(MoveTarget.USER_SIDE) .target(MoveTarget.USER_SIDE)
.attr(AddArenaTagAttr, ArenaTagType.CRAFTY_SHIELD, 1, true, true), .attr(AddArenaTagAttr, ArenaTagType.CRAFTY_SHIELD, 1, true, true)
.condition(failIfLastCondition),
new StatusMove(Moves.FLOWER_SHIELD, Type.FAIRY, -1, 10, -1, 0, 6) new StatusMove(Moves.FLOWER_SHIELD, Type.FAIRY, -1, 10, -1, 0, 6)
.target(MoveTarget.ALL) .target(MoveTarget.ALL)
.attr(StatStageChangeAttr, [ Stat.DEF ], 1, false, (user, target, move) => target.getTypes().includes(Type.GRASS) && !target.getTag(SemiInvulnerableTag)), .attr(StatStageChangeAttr, [ Stat.DEF ], 1, false, (user, target, move) => target.getTypes().includes(Type.GRASS) && !target.getTag(SemiInvulnerableTag)),
@ -8195,7 +8142,8 @@ export function initMoves() {
.target(MoveTarget.BOTH_SIDES) .target(MoveTarget.BOTH_SIDES)
.unimplemented(), .unimplemented(),
new SelfStatusMove(Moves.KINGS_SHIELD, Type.STEEL, -1, 10, -1, 4, 6) new SelfStatusMove(Moves.KINGS_SHIELD, Type.STEEL, -1, 10, -1, 4, 6)
.attr(ProtectAttr, BattlerTagType.KINGS_SHIELD), .attr(ProtectAttr, BattlerTagType.KINGS_SHIELD)
.condition(failIfLastCondition),
new StatusMove(Moves.PLAY_NICE, Type.NORMAL, -1, 20, -1, 0, 6) new StatusMove(Moves.PLAY_NICE, Type.NORMAL, -1, 20, -1, 0, 6)
.attr(StatStageChangeAttr, [ Stat.ATK ], -1), .attr(StatStageChangeAttr, [ Stat.ATK ], -1),
new StatusMove(Moves.CONFIDE, Type.NORMAL, -1, 20, -1, 0, 6) new StatusMove(Moves.CONFIDE, Type.NORMAL, -1, 20, -1, 0, 6)
@ -8218,7 +8166,8 @@ export function initMoves() {
new AttackMove(Moves.MYSTICAL_FIRE, Type.FIRE, MoveCategory.SPECIAL, 75, 100, 10, 100, 0, 6) new AttackMove(Moves.MYSTICAL_FIRE, Type.FIRE, MoveCategory.SPECIAL, 75, 100, 10, 100, 0, 6)
.attr(StatStageChangeAttr, [ Stat.SPATK ], -1), .attr(StatStageChangeAttr, [ Stat.SPATK ], -1),
new SelfStatusMove(Moves.SPIKY_SHIELD, Type.GRASS, -1, 10, -1, 4, 6) new SelfStatusMove(Moves.SPIKY_SHIELD, Type.GRASS, -1, 10, -1, 4, 6)
.attr(ProtectAttr, BattlerTagType.SPIKY_SHIELD), .attr(ProtectAttr, BattlerTagType.SPIKY_SHIELD)
.condition(failIfLastCondition),
new StatusMove(Moves.AROMATIC_MIST, Type.FAIRY, -1, 20, -1, 0, 6) new StatusMove(Moves.AROMATIC_MIST, Type.FAIRY, -1, 20, -1, 0, 6)
.attr(StatStageChangeAttr, [ Stat.SPDEF ], 1) .attr(StatStageChangeAttr, [ Stat.SPDEF ], 1)
.target(MoveTarget.NEAR_ALLY), .target(MoveTarget.NEAR_ALLY),
@ -8414,7 +8363,8 @@ export function initMoves() {
new AttackMove(Moves.FIRST_IMPRESSION, Type.BUG, MoveCategory.PHYSICAL, 90, 100, 10, -1, 2, 7) new AttackMove(Moves.FIRST_IMPRESSION, Type.BUG, MoveCategory.PHYSICAL, 90, 100, 10, -1, 2, 7)
.condition(new FirstMoveCondition()), .condition(new FirstMoveCondition()),
new SelfStatusMove(Moves.BANEFUL_BUNKER, Type.POISON, -1, 10, -1, 4, 7) new SelfStatusMove(Moves.BANEFUL_BUNKER, Type.POISON, -1, 10, -1, 4, 7)
.attr(ProtectAttr, BattlerTagType.BANEFUL_BUNKER), .attr(ProtectAttr, BattlerTagType.BANEFUL_BUNKER)
.condition(failIfLastCondition),
new AttackMove(Moves.SPIRIT_SHACKLE, Type.GHOST, MoveCategory.PHYSICAL, 80, 100, 10, 100, 0, 7) new AttackMove(Moves.SPIRIT_SHACKLE, Type.GHOST, MoveCategory.PHYSICAL, 80, 100, 10, 100, 0, 7)
.attr(AddBattlerTagAttr, BattlerTagType.TRAPPED, false, false, 1, 1, true) .attr(AddBattlerTagAttr, BattlerTagType.TRAPPED, false, false, 1, 1, true)
.makesContact(false), .makesContact(false),
@ -8657,6 +8607,7 @@ export function initMoves() {
/* Unused */ /* Unused */
new SelfStatusMove(Moves.MAX_GUARD, Type.NORMAL, -1, 10, -1, 4, 8) new SelfStatusMove(Moves.MAX_GUARD, Type.NORMAL, -1, 10, -1, 4, 8)
.attr(ProtectAttr) .attr(ProtectAttr)
.condition(failIfLastCondition)
.ignoresVirtual(), .ignoresVirtual(),
/* End Unused */ /* End Unused */
new AttackMove(Moves.DYNAMAX_CANNON, Type.DRAGON, MoveCategory.SPECIAL, 100, 100, 5, -1, 0, 8) new AttackMove(Moves.DYNAMAX_CANNON, Type.DRAGON, MoveCategory.SPECIAL, 100, 100, 5, -1, 0, 8)
@ -8835,7 +8786,8 @@ export function initMoves() {
.target(MoveTarget.USER_AND_ALLIES) .target(MoveTarget.USER_AND_ALLIES)
.ignoresProtect(), .ignoresProtect(),
new SelfStatusMove(Moves.OBSTRUCT, Type.DARK, 100, 10, -1, 4, 8) new SelfStatusMove(Moves.OBSTRUCT, Type.DARK, 100, 10, -1, 4, 8)
.attr(ProtectAttr, BattlerTagType.OBSTRUCT), .attr(ProtectAttr, BattlerTagType.OBSTRUCT)
.condition(failIfLastCondition),
new AttackMove(Moves.FALSE_SURRENDER, Type.DARK, MoveCategory.PHYSICAL, 80, -1, 10, -1, 0, 8), new AttackMove(Moves.FALSE_SURRENDER, Type.DARK, MoveCategory.PHYSICAL, 80, -1, 10, -1, 0, 8),
new AttackMove(Moves.METEOR_ASSAULT, Type.FIGHTING, MoveCategory.PHYSICAL, 150, 100, 5, -1, 0, 8) new AttackMove(Moves.METEOR_ASSAULT, Type.FIGHTING, MoveCategory.PHYSICAL, 150, 100, 5, -1, 0, 8)
.attr(RechargeAttr) .attr(RechargeAttr)
@ -9123,10 +9075,10 @@ export function initMoves() {
.attr(TeraBlastCategoryAttr) .attr(TeraBlastCategoryAttr)
.attr(TeraBlastTypeAttr) .attr(TeraBlastTypeAttr)
.attr(TeraBlastPowerAttr) .attr(TeraBlastPowerAttr)
.attr(StatStageChangeAttr, [ Stat.ATK, Stat.SPATK ], -1, true, (user, target, move) => user.isTerastallized() && user.isOfType(Type.STELLAR)) .attr(StatStageChangeAttr, [ Stat.ATK, Stat.SPATK ], -1, true, (user, target, move) => user.isTerastallized() && user.isOfType(Type.STELLAR)),
.partial(),
new SelfStatusMove(Moves.SILK_TRAP, Type.BUG, -1, 10, -1, 4, 9) new SelfStatusMove(Moves.SILK_TRAP, Type.BUG, -1, 10, -1, 4, 9)
.attr(ProtectAttr, BattlerTagType.SILK_TRAP), .attr(ProtectAttr, BattlerTagType.SILK_TRAP)
.condition(failIfLastCondition),
new AttackMove(Moves.AXE_KICK, Type.FIGHTING, MoveCategory.PHYSICAL, 120, 90, 10, 30, 0, 9) new AttackMove(Moves.AXE_KICK, Type.FIGHTING, MoveCategory.PHYSICAL, 120, 90, 10, 30, 0, 9)
.attr(MissEffectAttr, crashDamageFunc) .attr(MissEffectAttr, crashDamageFunc)
.attr(NoEffectAttr, crashDamageFunc) .attr(NoEffectAttr, crashDamageFunc)
@ -9318,7 +9270,8 @@ export function initMoves() {
.attr(PreMoveMessageAttr, doublePowerChanceMessageFunc) .attr(PreMoveMessageAttr, doublePowerChanceMessageFunc)
.attr(DoublePowerChanceAttr), .attr(DoublePowerChanceAttr),
new SelfStatusMove(Moves.BURNING_BULWARK, Type.FIRE, -1, 10, -1, 4, 9) new SelfStatusMove(Moves.BURNING_BULWARK, Type.FIRE, -1, 10, -1, 4, 9)
.attr(ProtectAttr, BattlerTagType.BURNING_BULWARK), .attr(ProtectAttr, BattlerTagType.BURNING_BULWARK)
.condition(failIfLastCondition),
new AttackMove(Moves.THUNDERCLAP, Type.ELECTRIC, MoveCategory.SPECIAL, 70, 100, 5, -1, 1, 9) new AttackMove(Moves.THUNDERCLAP, Type.ELECTRIC, MoveCategory.SPECIAL, 70, 100, 5, -1, 1, 9)
.condition((user, target, move) => user.scene.currentBattle.turnCommands[target.getBattlerIndex()]?.command === Command.FIGHT && !target.turnData.acted && allMoves[user.scene.currentBattle.turnCommands[target.getBattlerIndex()]?.move?.move!].category !== MoveCategory.STATUS), // TODO: is this bang correct? .condition((user, target, move) => user.scene.currentBattle.turnCommands[target.getBattlerIndex()]?.command === Command.FIGHT && !target.turnData.acted && allMoves[user.scene.currentBattle.turnCommands[target.getBattlerIndex()]?.move?.move!].category !== MoveCategory.STATUS), // TODO: is this bang correct?
new AttackMove(Moves.MIGHTY_CLEAVE, Type.ROCK, MoveCategory.PHYSICAL, 95, 100, 5, -1, 0, 9) new AttackMove(Moves.MIGHTY_CLEAVE, Type.ROCK, MoveCategory.PHYSICAL, 95, 100, 5, -1, 0, 9)

View File

@ -8,7 +8,7 @@ import { Abilities } from "#enums/abilities";
import { Moves } from "#enums/moves"; import { Moves } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { TimeOfDay } from "#enums/time-of-day"; import { TimeOfDay } from "#enums/time-of-day";
import { getPokemonNameWithAffix } from "#app/messages.js"; import { getPokemonNameWithAffix } from "#app/messages";
import i18next from "i18next"; import i18next from "i18next";
import { WeatherType } from "./weather"; import { WeatherType } from "./weather";

View File

@ -4,7 +4,7 @@ import { Type } from "./type";
import * as Utils from "../utils"; import * as Utils from "../utils";
import { ChangeMovePriorityAbAttr, applyAbAttrs } from "./ability"; import { ChangeMovePriorityAbAttr, applyAbAttrs } from "./ability";
import { ProtectAttr } from "./move"; import { ProtectAttr } from "./move";
import { BattlerIndex } from "#app/battle.js"; import { BattlerIndex } from "#app/battle";
import i18next from "i18next"; import i18next from "i18next";
export enum TerrainType { export enum TerrainType {

View File

@ -1,4 +1,4 @@
import { VariantTier } from "#app/enums/variant-tier.js"; import { VariantTier } from "#app/enums/variant-tier";
export type Variant = 0 | 1 | 2; export type Variant = 0 | 1 | 2;

View File

@ -64,6 +64,7 @@ export enum BattlerTagType {
STOCKPILING = "STOCKPILING", STOCKPILING = "STOCKPILING",
RECEIVE_DOUBLE_DAMAGE = "RECEIVE_DOUBLE_DAMAGE", RECEIVE_DOUBLE_DAMAGE = "RECEIVE_DOUBLE_DAMAGE",
ALWAYS_GET_HIT = "ALWAYS_GET_HIT", ALWAYS_GET_HIT = "ALWAYS_GET_HIT",
DISABLED = "DISABLED",
IGNORE_GHOST = "IGNORE_GHOST", IGNORE_GHOST = "IGNORE_GHOST",
IGNORE_DARK = "IGNORE_DARK", IGNORE_DARK = "IGNORE_DARK",
GULP_MISSILE_ARROKUDA = "GULP_MISSILE_ARROKUDA", GULP_MISSILE_ARROKUDA = "GULP_MISSILE_ARROKUDA",

View File

@ -1,13 +1,13 @@
/** /**
* Determines the cursor target when entering the shop phase. * Determines the row cursor target when entering the shop phase.
*/ */
export enum ShopCursorTarget { export enum ShopCursorTarget {
/** Cursor points to Reroll */ /** Cursor points to Reroll row */
REROLL, REROLL,
/** Cursor points to Items */ /** Cursor points to Rewards row */
ITEMS, REWARDS,
/** Cursor points to Shop */ /** Cursor points to Shop row */
SHOP, SHOP,
/** Cursor points to Check Team */ /** Cursor points to Check Team row */
CHECK_TEAM CHECK_TEAM
} }

View File

@ -1,7 +1,7 @@
import { ArenaTagSide } from "#app/data/arena-tag.js"; import { ArenaTagSide } from "#app/data/arena-tag";
import { ArenaTagType } from "#enums/arena-tag-type"; import { ArenaTagType } from "#enums/arena-tag-type";
import { TerrainType } from "#app/data/terrain.js"; import { TerrainType } from "#app/data/terrain";
import { WeatherType } from "#app/data/weather.js"; import { WeatherType } from "#app/data/weather";
/** Alias for all {@linkcode ArenaEvent} type strings */ /** Alias for all {@linkcode ArenaEvent} type strings */
export enum ArenaEventType { export enum ArenaEventType {

View File

@ -60,7 +60,7 @@ export class Arena {
this.scene.arenaBg.setTexture(`${biomeKey}_bg`); this.scene.arenaBg.setTexture(`${biomeKey}_bg`);
this.scene.arenaBgTransition.setTexture(`${biomeKey}_bg`); this.scene.arenaBgTransition.setTexture(`${biomeKey}_bg`);
// Redo this on initialise because during save/load the current wave isn't always // Redo this on initialize because during save/load the current wave isn't always
// set correctly during construction // set correctly during construction
this.updatePoolsForTimeOfDay(); this.updatePoolsForTimeOfDay();
} }
@ -289,7 +289,7 @@ export class Arena {
/** /**
* Sets weather to the override specified in overrides.ts * Sets weather to the override specified in overrides.ts
* @param weather new weather to set of type WeatherType * @param weather new {@linkcode WeatherType} to set
* @returns true to force trySetWeather to return true * @returns true to force trySetWeather to return true
*/ */
trySetWeatherOverride(weather: WeatherType): boolean { trySetWeatherOverride(weather: WeatherType): boolean {
@ -301,8 +301,8 @@ export class Arena {
/** /**
* Attempts to set a new weather to the battle * Attempts to set a new weather to the battle
* @param weather new weather to set of type WeatherType * @param weather {@linkcode WeatherType} new {@linkcode WeatherType} to set
* @param hasPokemonSource is the new weather from a pokemon * @param hasPokemonSource boolean if the new weather is from a pokemon
* @returns true if new weather set, false if no weather provided or attempting to set the same weather as currently in use * @returns true if new weather set, false if no weather provided or attempting to set the same weather as currently in use
*/ */
trySetWeather(weather: WeatherType, hasPokemonSource: boolean): boolean { trySetWeather(weather: WeatherType, hasPokemonSource: boolean): boolean {
@ -573,6 +573,12 @@ export class Arena {
this.ignoreAbilities = ignoreAbilities; this.ignoreAbilities = ignoreAbilities;
} }
/**
* Applies each `ArenaTag` in this Arena, based on which side (self, enemy, or both) is passed in as a parameter
* @param tagType Either an {@linkcode ArenaTagType} string, or an actual {@linkcode ArenaTag} class to filter which ones to apply
* @param side {@linkcode ArenaTagSide} which side's arena tags to apply
* @param args array of parameters that the called upon tags may need
*/
applyTagsForSide(tagType: ArenaTagType | Constructor<ArenaTag>, side: ArenaTagSide, ...args: unknown[]): void { applyTagsForSide(tagType: ArenaTagType | Constructor<ArenaTag>, side: ArenaTagSide, ...args: unknown[]): void {
let tags = typeof tagType === "string" let tags = typeof tagType === "string"
? this.tags.filter(t => t.tagType === tagType) ? this.tags.filter(t => t.tagType === tagType)
@ -583,11 +589,28 @@ export class Arena {
tags.forEach(t => t.apply(this, args)); tags.forEach(t => t.apply(this, args));
} }
/**
* Applies the specified tag to both sides (ie: both user and trainer's tag that match the Tag specified)
* by calling {@linkcode applyTagsForSide()}
* @param tagType Either an {@linkcode ArenaTagType} string, or an actual {@linkcode ArenaTag} class to filter which ones to apply
* @param args array of parameters that the called upon tags may need
*/
applyTags(tagType: ArenaTagType | Constructor<ArenaTag>, ...args: unknown[]): void { applyTags(tagType: ArenaTagType | Constructor<ArenaTag>, ...args: unknown[]): void {
this.applyTagsForSide(tagType, ArenaTagSide.BOTH, ...args); this.applyTagsForSide(tagType, ArenaTagSide.BOTH, ...args);
} }
addTag(tagType: ArenaTagType, turnCount: integer, sourceMove: Moves | undefined, sourceId: integer, side: ArenaTagSide = ArenaTagSide.BOTH, quiet: boolean = false, targetIndex?: BattlerIndex): boolean { /**
* Adds a new tag to the arena
* @param tagType {@linkcode ArenaTagType} the tag being added
* @param turnCount How many turns the tag lasts
* @param sourceMove {@linkcode Moves} the move the tag came from, or `undefined` if not from a move
* @param sourceId The ID of the pokemon in play the tag came from (see {@linkcode BattleScene.getPokemonById})
* @param side {@linkcode ArenaTagSide} which side(s) the tag applies to
* @param quiet If a message should be queued on screen to announce the tag being added
* @param targetIndex The {@linkcode BattlerIndex} of the target pokemon
* @returns `false` if there already exists a tag of this type in the Arena
*/
addTag(tagType: ArenaTagType, turnCount: number, sourceMove: Moves | undefined, sourceId: number, side: ArenaTagSide = ArenaTagSide.BOTH, quiet: boolean = false, targetIndex?: BattlerIndex): boolean {
const existingTag = this.getTagOnSide(tagType, side); const existingTag = this.getTagOnSide(tagType, side);
if (existingTag) { if (existingTag) {
existingTag.onOverlap(this); existingTag.onOverlap(this);
@ -600,6 +623,7 @@ export class Arena {
return false; return false;
} }
// creates a new tag object
const newTag = getArenaTag(tagType, turnCount || 0, sourceMove, sourceId, targetIndex, side); const newTag = getArenaTag(tagType, turnCount || 0, sourceMove, sourceId, targetIndex, side);
if (newTag) { if (newTag) {
this.tags.push(newTag); this.tags.push(newTag);
@ -613,6 +637,11 @@ export class Arena {
return true; return true;
} }
/**
* Attempts to get a tag from the Arena via {@linkcode getTagOnSide} that applies to both sides
* @param tagType The {@linkcode ArenaTagType} or {@linkcode ArenaTag} to get
* @returns either the {@linkcode ArenaTag}, or `undefined` if it isn't there
*/
getTag(tagType: ArenaTagType | Constructor<ArenaTag>): ArenaTag | undefined { getTag(tagType: ArenaTagType | Constructor<ArenaTag>): ArenaTag | undefined {
return this.getTagOnSide(tagType, ArenaTagSide.BOTH); return this.getTagOnSide(tagType, ArenaTagSide.BOTH);
} }
@ -621,16 +650,35 @@ export class Arena {
return !!this.getTag(tagType); return !!this.getTag(tagType);
} }
/**
* Attempts to get a tag from the Arena from a specific side (the tag passed in has to either apply to both sides, or the specific side only)
*
* eg: `MIST` only applies to the user's side, while `MUD_SPORT` applies to both user and enemy side
* @param tagType The {@linkcode ArenaTagType} or {@linkcode ArenaTag} to get
* @param side The {@linkcode ArenaTagSide} to look at
* @returns either the {@linkcode ArenaTag}, or `undefined` if it isn't there
*/
getTagOnSide(tagType: ArenaTagType | Constructor<ArenaTag>, side: ArenaTagSide): ArenaTag | undefined { getTagOnSide(tagType: ArenaTagType | Constructor<ArenaTag>, side: ArenaTagSide): ArenaTag | undefined {
return typeof(tagType) === "string" return typeof(tagType) === "string"
? this.tags.find(t => t.tagType === tagType && (side === ArenaTagSide.BOTH || t.side === ArenaTagSide.BOTH || t.side === side)) ? this.tags.find(t => t.tagType === tagType && (side === ArenaTagSide.BOTH || t.side === ArenaTagSide.BOTH || t.side === side))
: this.tags.find(t => t instanceof tagType && (side === ArenaTagSide.BOTH || t.side === ArenaTagSide.BOTH || t.side === side)); : this.tags.find(t => t instanceof tagType && (side === ArenaTagSide.BOTH || t.side === ArenaTagSide.BOTH || t.side === side));
} }
/**
* Uses {@linkcode findTagsOnSide} to filter (using the parameter function) for specific tags that apply to both sides
* @param tagPredicate a function mapping {@linkcode ArenaTag}s to `boolean`s
* @returns array of {@linkcode ArenaTag}s from which the Arena's tags return true and apply to both sides
*/
findTags(tagPredicate: (t: ArenaTag) => boolean): ArenaTag[] { findTags(tagPredicate: (t: ArenaTag) => boolean): ArenaTag[] {
return this.findTagsOnSide(tagPredicate, ArenaTagSide.BOTH); return this.findTagsOnSide(tagPredicate, ArenaTagSide.BOTH);
} }
/**
* Returns specific tags from the arena that pass the `tagPredicate` function passed in as a parameter, and apply to the given side
* @param tagPredicate a function mapping {@linkcode ArenaTag}s to `boolean`s
* @param side The {@linkcode ArenaTagSide} to look at
* @returns array of {@linkcode ArenaTag}s from which the Arena's tags return `true` and apply to the given side
*/
findTagsOnSide(tagPredicate: (t: ArenaTag) => boolean, side: ArenaTagSide): ArenaTag[] { findTagsOnSide(tagPredicate: (t: ArenaTag) => boolean, side: ArenaTagSide): ArenaTag[] {
return this.tags.filter(t => tagPredicate(t) && (side === ArenaTagSide.BOTH || t.side === ArenaTagSide.BOTH || t.side === side)); return this.tags.filter(t => tagPredicate(t) && (side === ArenaTagSide.BOTH || t.side === ArenaTagSide.BOTH || t.side === side));
} }

View File

@ -17,7 +17,7 @@ import { initMoveAnim, loadMoveAnimAssets } from "../data/battle-anims";
import { Status, StatusEffect, getRandomStatus } from "../data/status-effect"; import { Status, StatusEffect, getRandomStatus } from "../data/status-effect";
import { pokemonEvolutions, pokemonPrevolutions, SpeciesFormEvolution, SpeciesEvolutionCondition, FusionSpeciesFormEvolution } from "../data/pokemon-evolutions"; import { pokemonEvolutions, pokemonPrevolutions, SpeciesFormEvolution, SpeciesEvolutionCondition, FusionSpeciesFormEvolution } from "../data/pokemon-evolutions";
import { reverseCompatibleTms, tmSpecies, tmPoolTiers } from "../data/tms"; import { reverseCompatibleTms, tmSpecies, tmPoolTiers } from "../data/tms";
import { BattlerTag, BattlerTagLapseType, EncoreTag, GroundedTag, HighestStatBoostTag, TypeImmuneTag, getBattlerTag, SemiInvulnerableTag, TypeBoostTag, ExposedTag, DragonCheerTag, CritBoostTag, TrappedTag } from "../data/battler-tags"; import { BattlerTag, BattlerTagLapseType, EncoreTag, GroundedTag, HighestStatBoostTag, TypeImmuneTag, getBattlerTag, SemiInvulnerableTag, TypeBoostTag, MoveRestrictionBattlerTag, ExposedTag, DragonCheerTag, CritBoostTag, TrappedTag } from "../data/battler-tags";
import { WeatherType } from "../data/weather"; import { WeatherType } from "../data/weather";
import { ArenaTagSide, NoCritTag, WeakenMoveScreenTag } from "../data/arena-tag"; import { ArenaTagSide, NoCritTag, WeakenMoveScreenTag } from "../data/arena-tag";
import { Ability, AbAttr, StatMultiplierAbAttr, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, FieldPriorityMoveImmunityAbAttr, IgnoreOpponentStatStagesAbAttr, MoveImmunityAbAttr, PreDefendFullHpEndureAbAttr, ReceivedMoveDamageMultiplierAbAttr, ReduceStatusEffectDurationAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, WeightMultiplierAbAttr, allAbilities, applyAbAttrs, applyStatMultiplierAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs, UnsuppressableAbilityAbAttr, SuppressFieldAbilitiesAbAttr, NoFusionAbilityAbAttr, MultCritAbAttr, IgnoreTypeImmunityAbAttr, DamageBoostAbAttr, IgnoreTypeStatusEffectImmunityAbAttr, ConditionalCritAbAttr, applyFieldStatMultiplierAbAttrs, FieldMultiplyStatAbAttr, AddSecondStrikeAbAttr, UserFieldStatusEffectImmunityAbAttr, UserFieldBattlerTagImmunityAbAttr, BattlerTagImmunityAbAttr, MoveTypeChangeAbAttr, FullHpResistTypeAbAttr, applyCheckTrappedAbAttrs, CheckTrappedAbAttr } from "../data/ability"; import { Ability, AbAttr, StatMultiplierAbAttr, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, FieldPriorityMoveImmunityAbAttr, IgnoreOpponentStatStagesAbAttr, MoveImmunityAbAttr, PreDefendFullHpEndureAbAttr, ReceivedMoveDamageMultiplierAbAttr, ReduceStatusEffectDurationAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, WeightMultiplierAbAttr, allAbilities, applyAbAttrs, applyStatMultiplierAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs, UnsuppressableAbilityAbAttr, SuppressFieldAbilitiesAbAttr, NoFusionAbilityAbAttr, MultCritAbAttr, IgnoreTypeImmunityAbAttr, DamageBoostAbAttr, IgnoreTypeStatusEffectImmunityAbAttr, ConditionalCritAbAttr, applyFieldStatMultiplierAbAttrs, FieldMultiplyStatAbAttr, AddSecondStrikeAbAttr, UserFieldStatusEffectImmunityAbAttr, UserFieldBattlerTagImmunityAbAttr, BattlerTagImmunityAbAttr, MoveTypeChangeAbAttr, FullHpResistTypeAbAttr, applyCheckTrappedAbAttrs, CheckTrappedAbAttr } from "../data/ability";
@ -1427,22 +1427,26 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
} }
let multiplier = types.map(defType => { let multiplier = types.map(defType => {
const multiplier = new Utils.NumberHolder(getTypeDamageMultiplier(moveType, defType));
applyChallenges(this.scene.gameMode, ChallengeType.TYPE_EFFECTIVENESS, multiplier);
if (source) { if (source) {
const ignoreImmunity = new Utils.BooleanHolder(false); const ignoreImmunity = new Utils.BooleanHolder(false);
if (source.isActive(true) && source.hasAbilityWithAttr(IgnoreTypeImmunityAbAttr)) { if (source.isActive(true) && source.hasAbilityWithAttr(IgnoreTypeImmunityAbAttr)) {
applyAbAttrs(IgnoreTypeImmunityAbAttr, source, ignoreImmunity, simulated, moveType, defType); applyAbAttrs(IgnoreTypeImmunityAbAttr, source, ignoreImmunity, simulated, moveType, defType);
} }
if (ignoreImmunity.value) { if (ignoreImmunity.value) {
return 1; if (multiplier.value === 0) {
return 1;
}
} }
const exposedTags = this.findTags(tag => tag instanceof ExposedTag) as ExposedTag[]; const exposedTags = this.findTags(tag => tag instanceof ExposedTag) as ExposedTag[];
if (exposedTags.some(t => t.ignoreImmunity(defType, moveType))) { if (exposedTags.some(t => t.ignoreImmunity(defType, moveType))) {
return 1; if (multiplier.value === 0) {
return 1;
}
} }
} }
const multiplier = new Utils.NumberHolder(getTypeDamageMultiplier(moveType, defType));
applyChallenges(this.scene.gameMode, ChallengeType.TYPE_EFFECTIVENESS, multiplier);
return multiplier.value; return multiplier.value;
}).reduce((acc, cur) => acc * cur, 1) as TypeDamageMultiplier; }).reduce((acc, cur) => acc * cur, 1) as TypeDamageMultiplier;
@ -1720,7 +1724,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
}; };
this.fusionSpecies = this.scene.randomSpecies(this.scene.currentBattle?.waveIndex || 0, this.level, false, filter, true); this.fusionSpecies = this.scene.randomSpecies(this.scene.currentBattle?.waveIndex || 0, this.level, false, filter, true);
this.fusionAbilityIndex = (this.fusionSpecies.abilityHidden && hasHiddenAbility ? this.fusionSpecies.ability2 ? 2 : 1 : this.fusionSpecies.ability2 ? randAbilityIndex : 0); this.fusionAbilityIndex = (this.fusionSpecies.abilityHidden && hasHiddenAbility ? 2 : this.fusionSpecies.ability2 !== this.fusionSpecies.ability1 ? randAbilityIndex : 0);
this.fusionShiny = this.shiny; this.fusionShiny = this.shiny;
this.fusionVariant = this.variant; this.fusionVariant = this.variant;
@ -2278,7 +2282,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
if (!isTypeImmune) { if (!isTypeImmune) {
const levelMultiplier = (2 * source.level / 5 + 2); const levelMultiplier = (2 * source.level / 5 + 2);
const randomMultiplier = ((this.scene.randBattleSeedInt(16) + 85) / 100); const randomMultiplier = (this.randSeedIntRange(85, 100) / 100);
damage.value = Utils.toDmgValue((((levelMultiplier * power * sourceAtk.value / targetDef.value) / 50) + 2) damage.value = Utils.toDmgValue((((levelMultiplier * power * sourceAtk.value / targetDef.value) / 50) + 2)
* stabMultiplier.value * stabMultiplier.value
* typeMultiplier * typeMultiplier
@ -2660,11 +2664,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
} }
for (const tag of source.summonData.tags) { for (const tag of source.summonData.tags) {
if (!tag.isBatonPassable) {
// bypass those can not be passed via Baton Pass
const excludeTagTypes = new Set([BattlerTagType.DROWSY, BattlerTagType.INFATUATED, BattlerTagType.FIRE_BOOST]);
if (excludeTagTypes.has(tag.tagType)) {
continue; continue;
} }
@ -2674,6 +2674,33 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
this.updateInfo(); this.updateInfo();
} }
/**
* Gets whether the given move is currently disabled for this Pokemon.
*
* @param {Moves} moveId {@linkcode Moves} ID of the move to check
* @returns {boolean} `true` if the move is disabled for this Pokemon, otherwise `false`
*
* @see {@linkcode MoveRestrictionBattlerTag}
*/
isMoveRestricted(moveId: Moves): boolean {
return this.getRestrictingTag(moveId) !== null;
}
/**
* Gets the {@link MoveRestrictionBattlerTag} that is restricting a move, if it exists.
*
* @param {Moves} moveId {@linkcode Moves} ID of the move to check
* @returns {MoveRestrictionBattlerTag | null} the first tag on this Pokemon that restricts the move, or `null` if the move is not restricted.
*/
getRestrictingTag(moveId: Moves): MoveRestrictionBattlerTag | null {
for (const tag of this.findTags(t => t instanceof MoveRestrictionBattlerTag)) {
if ((tag as MoveRestrictionBattlerTag).isMoveRestricted(moveId)) {
return tag as MoveRestrictionBattlerTag;
}
}
return null;
}
getMoveHistory(): TurnMove[] { getMoveHistory(): TurnMove[] {
return this.battleSummonData.moveHistory; return this.battleSummonData.moveHistory;
} }
@ -3425,12 +3452,30 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
fusionCanvas.remove(); fusionCanvas.remove();
} }
/**
* Generates a random number using the current battle's seed, or the global seed if `this.scene.currentBattle` is falsy
* <!-- @import "../battle".Battle -->
* This calls either {@linkcode BattleScene.randBattleSeedInt}({@linkcode range}, {@linkcode min}) in `src/battle-scene.ts`
* which calls {@linkcode Battle.randSeedInt}(`scene`, {@linkcode range}, {@linkcode min}) in `src/battle.ts`
* which calls {@linkcode Utils.randSeedInt randSeedInt}({@linkcode range}, {@linkcode min}) in `src/utils.ts`,
* or it directly calls {@linkcode Utils.randSeedInt randSeedInt}({@linkcode range}, {@linkcode min}) in `src/utils.ts` if there is no current battle
*
* @param range How large of a range of random numbers to choose from. If {@linkcode range} <= 1, returns {@linkcode min}
* @param min The minimum integer to pick, default `0`
* @returns A random integer between {@linkcode min} and ({@linkcode min} + {@linkcode range} - 1)
*/
randSeedInt(range: integer, min: integer = 0): integer { randSeedInt(range: integer, min: integer = 0): integer {
return this.scene.currentBattle return this.scene.currentBattle
? this.scene.randBattleSeedInt(range, min) ? this.scene.randBattleSeedInt(range, min)
: Utils.randSeedInt(range, min); : Utils.randSeedInt(range, min);
} }
/**
* Generates a random number using the current battle's seed, or the global seed if `this.scene.currentBattle` is falsy
* @param min The minimum integer to generate
* @param max The maximum integer to generate
* @returns a random integer between {@linkcode min} and {@linkcode max} inclusive
*/
randSeedIntRange(min: integer, max: integer): integer { randSeedIntRange(min: integer, max: integer): integer {
return this.randSeedInt((max - min) + 1, min); return this.randSeedInt((max - min) + 1, min);
} }
@ -4460,10 +4505,9 @@ export interface AttackMoveResult {
} }
export class PokemonSummonData { export class PokemonSummonData {
/** [Atk, Def, SpAtk, SpDef, Spd, Acc, Eva] */
public statStages: number[] = [ 0, 0, 0, 0, 0, 0, 0 ]; public statStages: number[] = [ 0, 0, 0, 0, 0, 0, 0 ];
public moveQueue: QueuedMove[] = []; public moveQueue: QueuedMove[] = [];
public disabledMove: Moves = Moves.NONE;
public disabledTurns: number = 0;
public tags: BattlerTag[] = []; public tags: BattlerTag[] = [];
public abilitySuppressed: boolean = false; public abilitySuppressed: boolean = false;
public abilitiesApplied: Abilities[] = []; public abilitiesApplied: Abilities[] = [];
@ -4544,7 +4588,7 @@ export type DamageResult = HitResult.EFFECTIVE | HitResult.SUPER_EFFECTIVE | Hit
* It links to {@linkcode Move} class via the move ID. * It links to {@linkcode Move} class via the move ID.
* Compared to {@linkcode Move}, this class also tracks if a move has received. * Compared to {@linkcode Move}, this class also tracks if a move has received.
* PP Ups, amount of PP used, and things like that. * PP Ups, amount of PP used, and things like that.
* @see {@linkcode isUsable} - checks if move is disabled, out of PP, or not implemented. * @see {@linkcode isUsable} - checks if move is restricted, out of PP, or not implemented.
* @see {@linkcode getMove} - returns {@linkcode Move} object by looking it up via ID. * @see {@linkcode getMove} - returns {@linkcode Move} object by looking it up via ID.
* @see {@linkcode usePp} - removes a point of PP from the move. * @see {@linkcode usePp} - removes a point of PP from the move.
* @see {@linkcode getMovePp} - returns amount of PP a move currently has. * @see {@linkcode getMovePp} - returns amount of PP a move currently has.
@ -4564,11 +4608,25 @@ export class PokemonMove {
this.virtual = !!virtual; this.virtual = !!virtual;
} }
isUsable(pokemon: Pokemon, ignorePp?: boolean): boolean { /**
if (this.moveId && pokemon.summonData?.disabledMove === this.moveId) { * Checks whether the move can be selected or performed by a Pokemon, without consideration for the move's targets.
* The move is unusable if it is out of PP, restricted by an effect, or unimplemented.
*
* @param {Pokemon} pokemon {@linkcode Pokemon} that would be using this move
* @param {boolean} ignorePp If `true`, skips the PP check
* @param {boolean} ignoreRestrictionTags If `true`, skips the check for move restriction tags (see {@link MoveRestrictionBattlerTag})
* @returns `true` if the move can be selected and used by the Pokemon, otherwise `false`.
*/
isUsable(pokemon: Pokemon, ignorePp?: boolean, ignoreRestrictionTags?: boolean): boolean {
if (this.moveId && !ignoreRestrictionTags && pokemon.isMoveRestricted(this.moveId)) {
return false; return false;
} }
return (ignorePp || this.ppUsed < this.getMovePp() || this.getMove().pp === -1) && !this.getMove().name.endsWith(" (N)");
if (this.getMove().name.endsWith(" (N)")) {
return false;
}
return (ignorePp || this.ppUsed < this.getMovePp() || this.getMove().pp === -1);
} }
getMove(): Move { getMove(): Move {

View File

@ -16,7 +16,7 @@ import {
getIconForLatestInput, swap, getIconForLatestInput, swap,
} from "#app/configs/inputs/configHandler"; } from "#app/configs/inputs/configHandler";
import BattleScene from "./battle-scene"; import BattleScene from "./battle-scene";
import {SettingGamepad} from "#app/system/settings/settings-gamepad.js"; import {SettingGamepad} from "#app/system/settings/settings-gamepad";
import {SettingKeyboard} from "#app/system/settings/settings-keyboard"; import {SettingKeyboard} from "#app/system/settings/settings-keyboard";
import TouchControl from "#app/touch-controls"; import TouchControl from "#app/touch-controls";
import { Button } from "#enums/buttons"; import { Button } from "#enums/buttons";

View File

@ -78,6 +78,7 @@ export class LoadingScene extends SceneBase {
this.loadAtlas("overlay_hp_boss", "ui"); this.loadAtlas("overlay_hp_boss", "ui");
this.loadImage("overlay_exp", "ui"); this.loadImage("overlay_exp", "ui");
this.loadImage("icon_owned", "ui"); this.loadImage("icon_owned", "ui");
this.loadImage("icon_egg_move", "ui");
this.loadImage("ability_bar_left", "ui"); this.loadImage("ability_bar_left", "ui");
this.loadImage("bgm_bar", "ui"); this.loadImage("bgm_bar", "ui");
this.loadImage("party_exp_bar", "ui"); this.loadImage("party_exp_bar", "ui");
@ -164,6 +165,7 @@ export class LoadingScene extends SceneBase {
this.loadImage("saving_icon", "ui"); this.loadImage("saving_icon", "ui");
this.loadImage("discord", "ui"); this.loadImage("discord", "ui");
this.loadImage("google", "ui"); this.loadImage("google", "ui");
this.loadImage("settings_icon", "ui");
this.loadImage("default_bg", "arenas"); this.loadImage("default_bg", "arenas");
// Load arena images // Load arena images
@ -272,6 +274,7 @@ export class LoadingScene extends SceneBase {
this.loadImage("gacha_knob", "egg"); this.loadImage("gacha_knob", "egg");
this.loadImage("egg_list_bg", "ui"); this.loadImage("egg_list_bg", "ui");
this.loadImage("egg_summary_bg", "ui");
this.loadImage("end_m", "cg"); this.loadImage("end_m", "cg");
this.loadImage("end_f", "cg"); this.loadImage("end_f", "cg");

View File

@ -12,6 +12,7 @@
"typeImmunityHeal": "{{abilityName}} von {{pokemonNameWithAffix}} füllte einige KP auf!", "typeImmunityHeal": "{{abilityName}} von {{pokemonNameWithAffix}} füllte einige KP auf!",
"nonSuperEffectiveImmunity": "{{pokemonNameWithAffix}} vermeidet Schaden mit {{abilityName}}!", "nonSuperEffectiveImmunity": "{{pokemonNameWithAffix}} vermeidet Schaden mit {{abilityName}}!",
"disguiseAvoidedDamage": "Die Tarnung von {{pokemonNameWithAffix}} ist aufgeflogen!!", "disguiseAvoidedDamage": "Die Tarnung von {{pokemonNameWithAffix}} ist aufgeflogen!!",
"fullHpResistType": "Der Panzer von {{pokemonNameWithAffix}} funkelt und verzerrt die Wechselwirkungen zwischen den Typen!",
"moveImmunity": "Es hat keine Wirkung auf {{pokemonNameWithAffix}}...", "moveImmunity": "Es hat keine Wirkung auf {{pokemonNameWithAffix}}...",
"reverseDrain": "{{pokemonNameWithAffix}} saugt Kloakensoße auf!", "reverseDrain": "{{pokemonNameWithAffix}} saugt Kloakensoße auf!",
"postDefendTypeChange": "{{abilityName}} von {{pokemonNameWithAffix}} macht es zu einem {{typeName}}-Typ!", "postDefendTypeChange": "{{abilityName}} von {{pokemonNameWithAffix}} macht es zu einem {{typeName}}-Typ!",
@ -51,6 +52,7 @@
"postSummonTeravolt": "{{pokemonNameWithAffix}} strahlt eine knisternde Aura aus!", "postSummonTeravolt": "{{pokemonNameWithAffix}} strahlt eine knisternde Aura aus!",
"postSummonDarkAura": "{{pokemonNameWithAffix}} strahlt eine dunkle Aura aus!", "postSummonDarkAura": "{{pokemonNameWithAffix}} strahlt eine dunkle Aura aus!",
"postSummonFairyAura": "{{pokemonNameWithAffix}} strahlt eine Feenaura aus!", "postSummonFairyAura": "{{pokemonNameWithAffix}} strahlt eine Feenaura aus!",
"postSummonAuraBreak": "{{pokemonNameWithAffix}} kehrt die Wirkung aller Aura-Fähigkeiten um!",
"postSummonNeutralizingGas": "Reaktionsgas von {{pokemonNameWithAffix}} hat sich in der Umgebung ausgebreitet!", "postSummonNeutralizingGas": "Reaktionsgas von {{pokemonNameWithAffix}} hat sich in der Umgebung ausgebreitet!",
"postSummonAsOneGlastrier": "{{pokemonNameWithAffix}} verfügt über zwei Fähigkeiten!", "postSummonAsOneGlastrier": "{{pokemonNameWithAffix}} verfügt über zwei Fähigkeiten!",
"postSummonAsOneSpectrier": "{{pokemonNameWithAffix}} verfügt über zwei Fähigkeiten!", "postSummonAsOneSpectrier": "{{pokemonNameWithAffix}} verfügt über zwei Fähigkeiten!",

View File

@ -36,5 +36,6 @@
"matBlock": "Tatami-Schild", "matBlock": "Tatami-Schild",
"craftyShield": "Trickschutz", "craftyShield": "Trickschutz",
"tailwind": "Rückenwind", "tailwind": "Rückenwind",
"happyHour": "Goldene Zeiten" "happyHour": "Goldene Zeiten",
"safeguard": "Bodyguard"
} }

View File

@ -44,6 +44,7 @@
"moveNotImplemented": "{{moveName}} ist noch nicht implementiert und kann nicht ausgewählt werden.", "moveNotImplemented": "{{moveName}} ist noch nicht implementiert und kann nicht ausgewählt werden.",
"moveNoPP": "Es sind keine AP für diese Attacke mehr übrig!", "moveNoPP": "Es sind keine AP für diese Attacke mehr übrig!",
"moveDisabled": "{{moveName}} ist deaktiviert!", "moveDisabled": "{{moveName}} ist deaktiviert!",
"disableInterruptedMove": "{{moveName}} von {{pokemonNameWithAffix}} ist blockiert!",
"noPokeballForce": "Eine unsichtbare Kraft verhindert die Nutzung von Pokébällen.", "noPokeballForce": "Eine unsichtbare Kraft verhindert die Nutzung von Pokébällen.",
"noPokeballTrainer": "Du kannst das Pokémon eines anderen Trainers nicht fangen!", "noPokeballTrainer": "Du kannst das Pokémon eines anderen Trainers nicht fangen!",
"noPokeballMulti": "Du kannst erst einen Pokéball werfen, wenn nur noch ein Pokémon übrig ist!", "noPokeballMulti": "Du kannst erst einen Pokéball werfen, wenn nur noch ein Pokémon übrig ist!",

View File

@ -67,5 +67,7 @@
"saltCuredLapse": "{{pokemonNameWithAffix}} wurde durch {{moveName}} verletzt!", "saltCuredLapse": "{{pokemonNameWithAffix}} wurde durch {{moveName}} verletzt!",
"cursedOnAdd": "{{pokemonNameWithAffix}} nimmt einen Teil seiner KP und legt einen Fluch auf {{pokemonName}}!", "cursedOnAdd": "{{pokemonNameWithAffix}} nimmt einen Teil seiner KP und legt einen Fluch auf {{pokemonName}}!",
"cursedLapse": "{{pokemonNameWithAffix}} wurde durch den Fluch verletzt!", "cursedLapse": "{{pokemonNameWithAffix}} wurde durch den Fluch verletzt!",
"stockpilingOnAdd": "{{pokemonNameWithAffix}} hortet {{stockpiledCount}}!" "stockpilingOnAdd": "{{pokemonNameWithAffix}} hortet {{stockpiledCount}}!",
"disabledOnAdd": " {{moveName}} von {{pokemonNameWithAffix}} wurde blockiert!",
"disabledLapse": "{{moveName}} von {{pokemonNameWithAffix}} ist nicht länger blockiert!"
} }

View File

@ -51,5 +51,7 @@
"renamePokemon": "Pokémon umbennenen", "renamePokemon": "Pokémon umbennenen",
"rename": "Umbenennen", "rename": "Umbenennen",
"nickname": "Spitzname", "nickname": "Spitzname",
"errorServerDown": "Ups! Es gab einen Fehler beim Versuch\nden Server zu kontaktieren\nLasse dieses Fenster offen\nDu wirst automatisch neu verbunden." "errorServerDown": "Ups! Es gab einen Fehler beim Versuch\nden Server zu kontaktieren\nLasse dieses Fenster offen\nDu wirst automatisch neu verbunden.",
"noSaves": "Du hast keine gespeicherten Dateien!",
"tooManySaves": "Du hast zu viele gespeicherte Dateien!"
} }

View File

@ -47,10 +47,14 @@
"description": "Ändert das Wesen zu {{natureName}}. Schaltet dieses Wesen permanent für diesen Starter frei." "description": "Ändert das Wesen zu {{natureName}}. Schaltet dieses Wesen permanent für diesen Starter frei."
}, },
"DoubleBattleChanceBoosterModifierType": { "DoubleBattleChanceBoosterModifierType": {
"description": "Verdoppelt die Wahrscheinlichkeit, dass die nächsten {{battleCount}} Begegnungen mit wilden Pokémon ein Doppelkampf sind." "description": "Vervierfacht die Chance, dass ein Kampf ein Doppelkampf wird, für bis zu {{battleCount}} Kämpfe."
}, },
"TempStatStageBoosterModifierType": { "TempStatStageBoosterModifierType": {
"description": "Erhöht die {{stat}} aller Teammitglieder für 5 Kämpfe um eine Stufe." "description": "Erhöht {{stat}} aller Teammitglieder um {{amount}} für bis zu 5 Kämpfe.",
"extra": {
"stage": "eine Stufe",
"percentage": "30%"
}
}, },
"AttackTypeBoosterModifierType": { "AttackTypeBoosterModifierType": {
"description": "Erhöht die Stärke aller {{moveType}}-Attacken eines Pokémon um 20%." "description": "Erhöht die Stärke aller {{moveType}}-Attacken eines Pokémon um 20%."

View File

@ -100,7 +100,7 @@
"moveTouchControls": "Bewegung Touch Steuerung", "moveTouchControls": "Bewegung Touch Steuerung",
"shopOverlayOpacity": "Shop Overlay Deckkraft", "shopOverlayOpacity": "Shop Overlay Deckkraft",
"shopCursorTarget": "Shop-Cursor Ziel", "shopCursorTarget": "Shop-Cursor Ziel",
"items": "Items", "rewards": "Items",
"reroll": "Neu rollen", "reroll": "Neu rollen",
"shop": "Shop", "shop": "Shop",
"checkTeam": "Team überprüfen" "checkTeam": "Team überprüfen"

View File

@ -3,7 +3,7 @@
"badDreams": "{{pokemonName}} is tormented!", "badDreams": "{{pokemonName}} is tormented!",
"costar": "{{pokemonName}} copied {{allyName}}'s stat changes!", "costar": "{{pokemonName}} copied {{allyName}}'s stat changes!",
"iceFaceAvoidedDamage": "{{pokemonNameWithAffix}} avoided\ndamage with {{abilityName}}!", "iceFaceAvoidedDamage": "{{pokemonNameWithAffix}} avoided\ndamage with {{abilityName}}!",
"perishBody": "{{pokemonName}}'s {{abilityName}}\nwill faint both pokemon in 3 turns!", "perishBody": "{{pokemonName}}'s {{abilityName}}\nwill faint both Pokémon in 3 turns!",
"poisonHeal": "{{pokemonName}}'s {{abilityName}}\nrestored its HP a little!", "poisonHeal": "{{pokemonName}}'s {{abilityName}}\nrestored its HP a little!",
"trace": "{{pokemonName}} copied {{targetName}}'s\n{{abilityName}}!", "trace": "{{pokemonName}} copied {{targetName}}'s\n{{abilityName}}!",
"windPowerCharged": "Being hit by {{moveName}} charged {{pokemonName}} with power!", "windPowerCharged": "Being hit by {{moveName}} charged {{pokemonName}} with power!",
@ -52,6 +52,7 @@
"postSummonTeravolt": "{{pokemonNameWithAffix}} is radiating a bursting aura!", "postSummonTeravolt": "{{pokemonNameWithAffix}} is radiating a bursting aura!",
"postSummonDarkAura": "{{pokemonNameWithAffix}} is radiating a Dark Aura!", "postSummonDarkAura": "{{pokemonNameWithAffix}} is radiating a Dark Aura!",
"postSummonFairyAura": "{{pokemonNameWithAffix}} is radiating a Fairy Aura!", "postSummonFairyAura": "{{pokemonNameWithAffix}} is radiating a Fairy Aura!",
"postSummonAuraBreak": "{{pokemonNameWithAffix}} reversed all other Pokémon's auras!",
"postSummonNeutralizingGas": "{{pokemonNameWithAffix}}'s Neutralizing Gas filled the area!", "postSummonNeutralizingGas": "{{pokemonNameWithAffix}}'s Neutralizing Gas filled the area!",
"postSummonAsOneGlastrier": "{{pokemonNameWithAffix}} has two Abilities!", "postSummonAsOneGlastrier": "{{pokemonNameWithAffix}} has two Abilities!",
"postSummonAsOneSpectrier": "{{pokemonNameWithAffix}} has two Abilities!", "postSummonAsOneSpectrier": "{{pokemonNameWithAffix}} has two Abilities!",

View File

@ -39,5 +39,6 @@
"matBlock": "Mat Block", "matBlock": "Mat Block",
"craftyShield": "Crafty Shield", "craftyShield": "Crafty Shield",
"tailwind": "Tailwind", "tailwind": "Tailwind",
"happyHour": "Happy Hour" "happyHour": "Happy Hour",
"safeguard": "Safeguard"
} }

View File

@ -47,5 +47,11 @@
"tailwindOnRemovePlayer": "Your team's Tailwind petered out!", "tailwindOnRemovePlayer": "Your team's Tailwind petered out!",
"tailwindOnRemoveEnemy": "The opposing team's Tailwind petered out!", "tailwindOnRemoveEnemy": "The opposing team's Tailwind petered out!",
"happyHourOnAdd": "Everyone is caught up in the happy atmosphere!", "happyHourOnAdd": "Everyone is caught up in the happy atmosphere!",
"happyHourOnRemove": "The atmosphere returned to normal." "happyHourOnRemove": "The atmosphere returned to normal.",
"safeguardOnAdd": "The whole field is cloaked in a mystical veil!",
"safeguardOnAddPlayer": "Your team cloaked itself in a mystical veil!",
"safeguardOnAddEnemy": "The opposing team cloaked itself in a mystical veil!",
"safeguardOnRemove": "The field is no longer protected by Safeguard!",
"safeguardOnRemovePlayer": "Your team is no longer protected by Safeguard!",
"safeguardOnRemoveEnemy": "The opposing team is no longer protected by Safeguard!"
} }

View File

@ -44,6 +44,7 @@
"moveNotImplemented": "{{moveName}} is not yet implemented and cannot be selected.", "moveNotImplemented": "{{moveName}} is not yet implemented and cannot be selected.",
"moveNoPP": "There's no PP left for\nthis move!", "moveNoPP": "There's no PP left for\nthis move!",
"moveDisabled": "{{moveName}} is disabled!", "moveDisabled": "{{moveName}} is disabled!",
"disableInterruptedMove": "{{pokemonNameWithAffix}}'s {{moveName}}\nis disabled!",
"noPokeballForce": "An unseen force\nprevents using Poké Balls.", "noPokeballForce": "An unseen force\nprevents using Poké Balls.",
"noPokeballTrainer": "You can't catch\nanother trainer's Pokémon!", "noPokeballTrainer": "You can't catch\nanother trainer's Pokémon!",
"noPokeballMulti": "You can only throw a Poké Ball\nwhen there is one Pokémon remaining!", "noPokeballMulti": "You can only throw a Poké Ball\nwhen there is one Pokémon remaining!",
@ -61,6 +62,7 @@
"skipItemQuestion": "Are you sure you want to skip taking an item?", "skipItemQuestion": "Are you sure you want to skip taking an item?",
"itemStackFull": "The stack for {{fullItemName}} is full.\nYou will receive {{itemName}} instead.", "itemStackFull": "The stack for {{fullItemName}} is full.\nYou will receive {{itemName}} instead.",
"eggHatching": "Oh?", "eggHatching": "Oh?",
"eggSkipPrompt": "Skip to egg summary?",
"ivScannerUseQuestion": "Use IV Scanner on {{pokemonName}}?", "ivScannerUseQuestion": "Use IV Scanner on {{pokemonName}}?",
"wildPokemonWithAffix": "Wild {{pokemonName}}", "wildPokemonWithAffix": "Wild {{pokemonName}}",
"foePokemonWithAffix": "Foe {{pokemonName}}", "foePokemonWithAffix": "Foe {{pokemonName}}",

View File

@ -67,5 +67,7 @@
"saltCuredLapse": "{{pokemonNameWithAffix}} is hurt by {{moveName}}!", "saltCuredLapse": "{{pokemonNameWithAffix}} is hurt by {{moveName}}!",
"cursedOnAdd": "{{pokemonNameWithAffix}} cut its own HP and put a curse on the {{pokemonName}}!", "cursedOnAdd": "{{pokemonNameWithAffix}} cut its own HP and put a curse on the {{pokemonName}}!",
"cursedLapse": "{{pokemonNameWithAffix}} is afflicted by the Curse!", "cursedLapse": "{{pokemonNameWithAffix}} is afflicted by the Curse!",
"stockpilingOnAdd": "{{pokemonNameWithAffix}} stockpiled {{stockpiledCount}}!" "stockpilingOnAdd": "{{pokemonNameWithAffix}} stockpiled {{stockpiledCount}}!",
"disabledOnAdd": "{{pokemonNameWithAffix}}'s {{moveName}}\nwas disabled!",
"disabledLapse": "{{pokemonNameWithAffix}}'s {{moveName}}\nis no longer disabled."
} }

View File

@ -1,6 +1,6 @@
{ {
"title": "Challenge Modifiers", "title": "Challenge Modifiers",
"illegalEvolution": "{{pokemon}} changed into an ineligble pokémon\nfor this challenge!", "illegalEvolution": "{{pokemon}} changed into an ineligible Pokémon\nfor this challenge!",
"noneSelected": "None Selected", "noneSelected": "None Selected",
"singleGeneration": { "singleGeneration": {
"name": "Mono Gen", "name": "Mono Gen",

View File

@ -413,7 +413,7 @@
}, },
"ariana": { "ariana": {
"encounter": { "encounter": {
"1": "Hold it right there! We can't someone on the loose.\n$It's harmful to Team Rocket's pride, you see.", "1": "Hold it right there!\nWe can't have someone on the loose.\n$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...\n$I just put my faith in Giovanni and do as I am told", "2": "I don't know or care if what I'm doing is right or wrong...\n$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!" "3": "Your trip ends here. I'm going to take you down!"
}, },

View File

@ -51,5 +51,7 @@
"renamePokemon": "Rename Pokémon", "renamePokemon": "Rename Pokémon",
"rename": "Rename", "rename": "Rename",
"nickname": "Nickname", "nickname": "Nickname",
"errorServerDown": "Oops! There was an issue contacting the server.\n\nYou may leave this window open,\nthe game will automatically reconnect." "errorServerDown": "Oops! There was an issue contacting the server.\n\nYou may leave this window open,\nthe game will automatically reconnect.",
"noSaves": "You don't have any save files on record!",
"tooManySaves": "You have too many save files on record!"
} }

View File

@ -47,10 +47,14 @@
"description": "Changes a Pokémon's nature to {{natureName}} and permanently unlocks the nature for the starter." "description": "Changes a Pokémon's nature to {{natureName}} and permanently unlocks the nature for the starter."
}, },
"DoubleBattleChanceBoosterModifierType": { "DoubleBattleChanceBoosterModifierType": {
"description": "Doubles the chance of an encounter being a double battle for {{battleCount}} battles." "description": "Quadruples the chance of an encounter being a double battle for up to {{battleCount}} battles."
}, },
"TempStatStageBoosterModifierType": { "TempStatStageBoosterModifierType": {
"description": "Increases the {{stat}} of all party members by 1 stage for 5 battles." "description": "Increases the {{stat}} of all party members by {{amount}} for up to 5 battles.",
"extra": {
"stage": "1 stage",
"percentage": "30%"
}
}, },
"AttackTypeBoosterModifierType": { "AttackTypeBoosterModifierType": {
"description": "Increases the power of a Pokémon's {{moveType}}-type moves by 20%." "description": "Increases the power of a Pokémon's {{moveType}}-type moves by 20%."

View File

@ -65,5 +65,6 @@
"suppressAbilities": "{{pokemonName}}'s ability\nwas suppressed!", "suppressAbilities": "{{pokemonName}}'s ability\nwas suppressed!",
"revivalBlessing": "{{pokemonName}} was revived!", "revivalBlessing": "{{pokemonName}} was revived!",
"swapArenaTags": "{{pokemonName}} swapped the battle effects affecting each side of the field!", "swapArenaTags": "{{pokemonName}} swapped the battle effects affecting each side of the field!",
"exposedMove": "{{pokemonName}} identified\n{{targetPokemonName}}!" "exposedMove": "{{pokemonName}} identified\n{{targetPokemonName}}!",
"safeguard": "{{targetName}} is protected by Safeguard!"
} }

View File

@ -100,7 +100,7 @@
"moveTouchControls": "Move Touch Controls", "moveTouchControls": "Move Touch Controls",
"shopOverlayOpacity": "Shop Overlay Opacity", "shopOverlayOpacity": "Shop Overlay Opacity",
"shopCursorTarget": "Shop Cursor Target", "shopCursorTarget": "Shop Cursor Target",
"items": "Items", "rewards": "Rewards",
"reroll": "Reroll", "reroll": "Reroll",
"shop": "Shop", "shop": "Shop",
"checkTeam": "Check Team" "checkTeam": "Check Team"

View File

@ -12,6 +12,7 @@
"blockItemTheft": "¡{{pokemonNameWithAffix}} evitó el robo gracias a {{abilityName}}!", "blockItemTheft": "¡{{pokemonNameWithAffix}} evitó el robo gracias a {{abilityName}}!",
"typeImmunityHeal": "¡{{pokemonNameWithAffix}} restauró algunos de sus PS gracias a {{abilityName}}!", "typeImmunityHeal": "¡{{pokemonNameWithAffix}} restauró algunos de sus PS gracias a {{abilityName}}!",
"nonSuperEffectiveImmunity": "¡{{pokemonNameWithAffix}} evitó el daño gracias a {{abilityName}}!", "nonSuperEffectiveImmunity": "¡{{pokemonNameWithAffix}} evitó el daño gracias a {{abilityName}}!",
"fullHpResistType": "¡{{pokemonNameWithAffix}} ha hecho brillar su caparazón\ny ha alterado su compatibilidad entre tipos!",
"moveImmunity": "¡No afecta a {{pokemonNameWithAffix}}!", "moveImmunity": "¡No afecta a {{pokemonNameWithAffix}}!",
"reverseDrain": "¡{{pokemonNameWithAffix}} absorbió lodo líquido!", "reverseDrain": "¡{{pokemonNameWithAffix}} absorbió lodo líquido!",
"postDefendTypeChange": "¡{{abilityName}} de {{pokemonNameWithAffix}} cambió a tipo {{typeName}}!", "postDefendTypeChange": "¡{{abilityName}} de {{pokemonNameWithAffix}} cambió a tipo {{typeName}}!",
@ -51,6 +52,7 @@
"postSummonTeravolt": "¡{{pokemonNameWithAffix}} irradia un aura chisporroteante!", "postSummonTeravolt": "¡{{pokemonNameWithAffix}} irradia un aura chisporroteante!",
"postSummonDarkAura": "¡{{pokemonNameWithAffix}} irradia un aura oscura!", "postSummonDarkAura": "¡{{pokemonNameWithAffix}} irradia un aura oscura!",
"postSummonFairyAura": "¡{{pokemonNameWithAffix}} irradia un aura feérica!", "postSummonFairyAura": "¡{{pokemonNameWithAffix}} irradia un aura feérica!",
"postSummonAuraBreak": "¡{{pokemonNameWithAffix}} ha invertido todas las auras!",
"postSummonNeutralizingGas": "¡El Gas Reactivo de {{pokemonNameWithAffix}} se propaga por toda la zona!", "postSummonNeutralizingGas": "¡El Gas Reactivo de {{pokemonNameWithAffix}} se propaga por toda la zona!",
"postSummonAsOneGlastrier": "¡{{pokemonNameWithAffix}} tiene dos Habilidades!", "postSummonAsOneGlastrier": "¡{{pokemonNameWithAffix}} tiene dos Habilidades!",
"postSummonAsOneSpectrier": "¡{{pokemonNameWithAffix}} tiene dos Habilidades!", "postSummonAsOneSpectrier": "¡{{pokemonNameWithAffix}} tiene dos Habilidades!",

View File

@ -36,5 +36,6 @@
"matBlock": "Escudo Tatami", "matBlock": "Escudo Tatami",
"craftyShield": "Truco Defensa", "craftyShield": "Truco Defensa",
"tailwind": "Viento Afín", "tailwind": "Viento Afín",
"happyHour": "Paga Extra" "happyHour": "Paga Extra",
"safeguard": "Velo Sagrado"
} }

View File

@ -42,6 +42,7 @@
"moveNotImplemented": "{{moveName}} aún no está implementado y no se puede seleccionar.", "moveNotImplemented": "{{moveName}} aún no está implementado y no se puede seleccionar.",
"moveNoPP": "¡No hay suficientes PP\npara este movimiento!", "moveNoPP": "¡No hay suficientes PP\npara este movimiento!",
"moveDisabled": "!No puede usar {{moveName}} porque ha sido anulado!", "moveDisabled": "!No puede usar {{moveName}} porque ha sido anulado!",
"disableInterruptedMove": "¡Se ha anulado el movimiento {{moveName}}\nde {{pokemonNameWithAffix}}!",
"noPokeballForce": "Una fuerza misteriosa\nte impide usar Poké Balls.", "noPokeballForce": "Una fuerza misteriosa\nte impide usar Poké Balls.",
"noPokeballTrainer": "¡No puedes atrapar a los\nPokémon de los demás!", "noPokeballTrainer": "¡No puedes atrapar a los\nPokémon de los demás!",
"noPokeballMulti": "¡No se pueden lanzar Poké Balls\ncuando hay más de un Pokémon!", "noPokeballMulti": "¡No se pueden lanzar Poké Balls\ncuando hay más de un Pokémon!",

View File

@ -67,5 +67,7 @@
"saltCuredLapse": "¡{{moveName}} ha herido a {{pokemonNameWithAffix}}!", "saltCuredLapse": "¡{{moveName}} ha herido a {{pokemonNameWithAffix}}!",
"cursedOnAdd": "¡{{pokemonNameWithAffix}} sacrifica algunos PS y maldice a {{pokemonName}}!", "cursedOnAdd": "¡{{pokemonNameWithAffix}} sacrifica algunos PS y maldice a {{pokemonName}}!",
"cursedLapse": "¡{{pokemonNameWithAffix}} es víctima de una maldición!", "cursedLapse": "¡{{pokemonNameWithAffix}} es víctima de una maldición!",
"stockpilingOnAdd": "¡{{pokemonNameWithAffix}} ha reservado energía por {{stockpiledCount}}ª vez!" "stockpilingOnAdd": "¡{{pokemonNameWithAffix}} ha reservado energía por {{stockpiledCount}}ª vez!",
"disabledOnAdd": "¡Se ha anulado el movimiento {{moveName}}\nde {{pokemonNameWithAffix}}!",
"disabledLapse": "¡El movimiento {{moveName}} de {{pokemonNameWithAffix}} \n ya no está anulado!"
} }

View File

@ -14,14 +14,14 @@
"register": "Registrarse", "register": "Registrarse",
"emptyUsername": "El usuario no puede estar vacío", "emptyUsername": "El usuario no puede estar vacío",
"invalidLoginUsername": "El usuario no es válido", "invalidLoginUsername": "El usuario no es válido",
"invalidRegisterUsername": "El usuario solo puede contener letras, números y guiones bajos", "invalidRegisterUsername": "El usuario solo puede contener letras, números y guiones bajos.",
"invalidLoginPassword": "La contraseña no es válida", "invalidLoginPassword": "La contraseña no es válida",
"invalidRegisterPassword": "La contraseña debe tener 6 o más caracteres.", "invalidRegisterPassword": "La contraseña debe tener 6 o más caracteres.",
"usernameAlreadyUsed": "El usuario ya está en uso", "usernameAlreadyUsed": "El usuario ya está en uso",
"accountNonExistent": "El usuario no existe", "accountNonExistent": "El usuario no existe",
"unmatchingPassword": "La contraseña no coincide", "unmatchingPassword": "La contraseña no coincide",
"passwordNotMatchingConfirmPassword": "Las contraseñas deben coincidir", "passwordNotMatchingConfirmPassword": "Las contraseñas deben coincidir",
"confirmPassword": "Confirmar Contra.", "confirmPassword": "Confirmar contraseña",
"registrationAgeWarning": "Al registrarte, confirmas tener 13 o más años de edad.", "registrationAgeWarning": "Al registrarte, confirmas tener 13 o más años de edad.",
"backToLogin": "Volver al Login", "backToLogin": "Volver al Login",
"failedToLoadSaveData": "No se han podido cargar los datos guardados. Por favor, recarga la página.\nSi el fallo continúa, por favor comprueba #announcements en nuestro Discord.", "failedToLoadSaveData": "No se han podido cargar los datos guardados. Por favor, recarga la página.\nSi el fallo continúa, por favor comprueba #announcements en nuestro Discord.",
@ -51,5 +51,7 @@
"renamePokemon": "Renombrar Pokémon.", "renamePokemon": "Renombrar Pokémon.",
"rename": "Renombrar", "rename": "Renombrar",
"nickname": "Apodo", "nickname": "Apodo",
"errorServerDown": "¡Ups! Ha habido un problema al contactar con el servidor.\n\nPuedes mantener esta ventana abierta, el juego se reconectará automáticamente." "errorServerDown": "¡Ups! Ha habido un problema al contactar con el servidor.\n\nPuedes mantener esta ventana abierta, el juego se reconectará automáticamente.",
"noSaves": "No tienes ninguna partida guardada registrada!",
"tooManySaves": "¡Tienes demasiadas partidas guardadas registradas!"
} }

View File

@ -47,10 +47,14 @@
"description": "Cambia la naturaleza de un Pokémon a {{natureName}} y desbloquea permanentemente dicha naturaleza para el inicial." "description": "Cambia la naturaleza de un Pokémon a {{natureName}} y desbloquea permanentemente dicha naturaleza para el inicial."
}, },
"DoubleBattleChanceBoosterModifierType": { "DoubleBattleChanceBoosterModifierType": {
"description": "Duplica la posibilidad de que un encuentro sea una combate doble durante {{battleCount}} combates." "description": "Cuadruplica la posibilidad de que un encuentro sea una combate doble durante {{battleCount}} combates."
}, },
"TempStatStageBoosterModifierType": { "TempStatStageBoosterModifierType": {
"description": "Aumenta la est. {{stat}} de todos los miembros del equipo en 1 nivel durante 5 combates." "description": "Aumenta la est. {{stat}} de todos los miembros del equipo en {{amount}} durante 5 combates.",
"extra": {
"stage": "1 nivel",
"percentage": "30%"
}
}, },
"AttackTypeBoosterModifierType": { "AttackTypeBoosterModifierType": {
"description": "Aumenta la potencia de los movimientos de tipo {{moveType}} de un Pokémon en un 20%." "description": "Aumenta la potencia de los movimientos de tipo {{moveType}} de un Pokémon en un 20%."

View File

@ -100,7 +100,7 @@
"moveTouchControls": "Controles táctiles", "moveTouchControls": "Controles táctiles",
"shopOverlayOpacity": "Opacidad de la fase de compra", "shopOverlayOpacity": "Opacidad de la fase de compra",
"shopCursorTarget": "Cursor de la tienda", "shopCursorTarget": "Cursor de la tienda",
"items": "Objetos", "rewards": "Objetos",
"reroll": "Actualizar", "reroll": "Actualizar",
"shop": "Tienda", "shop": "Tienda",
"checkTeam": "Ver equipo" "checkTeam": "Ver equipo"

View File

@ -3,14 +3,15 @@
"badDreams": "{{pokemonName}} a le sommeil agité !", "badDreams": "{{pokemonName}} a le sommeil agité !",
"costar": "{{pokemonName}} copie les changements de stats\nde {{allyName}} !", "costar": "{{pokemonName}} copie les changements de stats\nde {{allyName}} !",
"iceFaceAvoidedDamage": "{{pokemonNameWithAffix}} évite les dégâts\navec {{abilityName}} !", "iceFaceAvoidedDamage": "{{pokemonNameWithAffix}} évite les dégâts\navec {{abilityName}} !",
"perishBody": "{{abilityName}} de {{pokemonName}}\nmettra les deux Pokémon K.O. dans trois tours !", "perishBody": "{{abilityName}} de {{pokemonName}}\nmettra les deux Pokémon K.O. dans trois tours !",
"poisonHeal": "{{abilityName}} de {{pokemonName}}\nrestaure un peu ses PV !", "poisonHeal": "{{abilityName}} de {{pokemonName}}\nrestaure un peu ses PV !",
"trace": "{{pokemonName}} copie le talent {{abilityName}}\nde {{targetName}} !", "trace": "{{pokemonName}} copie le talent {{abilityName}}\nde {{targetName}} !",
"windPowerCharged": "{{pokemonName}} a été touché par la capacité {{moveName}} et se charge en électricité !", "windPowerCharged": "{{pokemonName}} a été touché par la capacité {{moveName}} et se charge en électricité !",
"quickDraw": "Tir Vif permet à {{pokemonName}}\ndagir plus vite que dhabitude !", "quickDraw": "Tir Vif permet à {{pokemonName}}\ndagir plus vite que dhabitude !",
"blockItemTheft": "{{abilityName}} de {{pokemonNameWithAffix}}\nempêche son objet dêtre volé !", "blockItemTheft": "{{abilityName}} de {{pokemonNameWithAffix}}\nempêche son objet dêtre volé !",
"typeImmunityHeal": "{{abilityName}} de {{pokemonNameWithAffix}}\nrestaure un peu ses PV !", "typeImmunityHeal": "{{abilityName}} de {{pokemonNameWithAffix}}\nrestaure un peu ses PV !",
"nonSuperEffectiveImmunity": "{{pokemonNameWithAffix}} évite\nles dégâts avec {{abilityName}} !", "nonSuperEffectiveImmunity": "{{pokemonNameWithAffix}} évite\nles dégâts avec {{abilityName}} !",
"fullHpResistType": "{{pokemonNameWithAffix}} fait briller sa carapace\net fausse les affinités de type !",
"disguiseAvoidedDamage": "Le déguisement de {{pokemonNameWithAffix}}\ntombe !", "disguiseAvoidedDamage": "Le déguisement de {{pokemonNameWithAffix}}\ntombe !",
"moveImmunity": "Ça naffecte pas {{pokemonNameWithAffix}}…", "moveImmunity": "Ça naffecte pas {{pokemonNameWithAffix}}…",
"reverseDrain": "{{pokemonNameWithAffix}} aspire\nle suintement !", "reverseDrain": "{{pokemonNameWithAffix}} aspire\nle suintement !",
@ -33,12 +34,12 @@
"battlerTagImmunity": "{{abilityName}} de {{pokemonNameWithAffix}}\nempêche {{battlerTagName}} !", "battlerTagImmunity": "{{abilityName}} de {{pokemonNameWithAffix}}\nempêche {{battlerTagName}} !",
"forewarn": "La capacité {{moveName}}\nde {{pokemonNameWithAffix}} a été détectée !", "forewarn": "La capacité {{moveName}}\nde {{pokemonNameWithAffix}} a été détectée !",
"frisk": "{{pokemonNameWithAffix}} fouille {{opponentName}}\net trouve son talent {{opponentAbilityName}} !", "frisk": "{{pokemonNameWithAffix}} fouille {{opponentName}}\net trouve son talent {{opponentAbilityName}} !",
"postWeatherLapseHeal": "{{abilityName}} de {{pokemonNameWithAffix}}\nrestaure un peu ses PV !", "postWeatherLapseHeal": "{{abilityName}} de {{pokemonNameWithAffix}}\nrestaure un peu ses PV !",
"postWeatherLapseDamage": "{{pokemonNameWithAffix}} est blessé\npar son talent {{abilityName}} !", "postWeatherLapseDamage": "{{pokemonNameWithAffix}} est blessé\npar son talent {{abilityName}} !",
"postTurnLootCreateEatenBerry": "{{pokemonNameWithAffix}} a récolté\nune {{berryName}} !", "postTurnLootCreateEatenBerry": "{{pokemonNameWithAffix}} a récolté\nune {{berryName}} !",
"postTurnHeal": "{{abilityName}} de {{pokemonNameWithAffix}}\nrestaure un peu ses PV !", "postTurnHeal": "{{abilityName}} de {{pokemonNameWithAffix}}\nrestaure un peu ses PV !",
"fetchBall": "{{pokemonNameWithAffix}} trouve\nune {{pokeballName}} !", "fetchBall": "{{pokemonNameWithAffix}} trouve\nune {{pokeballName}} !",
"healFromBerryUse": "{{abilityName}} de {{pokemonNameWithAffix}}\nrestaure un peu ses PV !", "healFromBerryUse": "{{abilityName}} de {{pokemonNameWithAffix}}\nrestaure un peu ses PV !",
"arenaTrap": "{{pokemonNameWithAffix}} empêche\nles changements grâce à son talent {{abilityName}} !", "arenaTrap": "{{pokemonNameWithAffix}} empêche\nles changements grâce à son talent {{abilityName}} !",
"postBattleLoot": "{{pokemonNameWithAffix}} ramasse\nlobjet {{itemName}} !", "postBattleLoot": "{{pokemonNameWithAffix}} ramasse\nlobjet {{itemName}} !",
"postFaintContactDamage": "{{pokemonNameWithAffix}} est blessé\npar son talent {{abilityName}} !", "postFaintContactDamage": "{{pokemonNameWithAffix}} est blessé\npar son talent {{abilityName}} !",
@ -49,8 +50,9 @@
"postSummonAnticipation": "{{pokemonNameWithAffix}}\nest tout tremblant !", "postSummonAnticipation": "{{pokemonNameWithAffix}}\nest tout tremblant !",
"postSummonTurboblaze": "{{pokemonNameWithAffix}} dégage\nune aura de flammes incandescentes !", "postSummonTurboblaze": "{{pokemonNameWithAffix}} dégage\nune aura de flammes incandescentes !",
"postSummonTeravolt": "{{pokemonNameWithAffix}} dégage\nune aura électrique instable !", "postSummonTeravolt": "{{pokemonNameWithAffix}} dégage\nune aura électrique instable !",
"postSummonDarkAura": "{{pokemonNameWithAffix}} dégage\nune aura ténébreuse !", "postSummonDarkAura": "{{pokemonNameWithAffix}} dégage\nune aura ténébreuse !",
"postSummonFairyAura": "{{pokemonNameWithAffix}} dégage\nune aura enchanteresse !", "postSummonFairyAura": "{{pokemonNameWithAffix}} dégage\nune aura enchanteresse !",
"postSummonAuraBreak": "{{pokemonNameWithAffix}} inverse\ntoutes les auras !",
"postSummonNeutralizingGas": "Le gaz inhibiteur {{pokemonNameWithAffix}}\nenvahit les lieux !", "postSummonNeutralizingGas": "Le gaz inhibiteur {{pokemonNameWithAffix}}\nenvahit les lieux !",
"postSummonAsOneGlastrier": "{{pokemonNameWithAffix}}\na deux talents !", "postSummonAsOneGlastrier": "{{pokemonNameWithAffix}}\na deux talents !",
"postSummonAsOneSpectrier": "{{pokemonNameWithAffix}}\na deux talents !", "postSummonAsOneSpectrier": "{{pokemonNameWithAffix}}\na deux talents !",

View File

@ -227,7 +227,7 @@
"name": "Angry Birds" "name": "Angry Birds"
}, },
"MONO_POISON": { "MONO_POISON": {
"name": "Touche moi je tempoisonne !" "name": "Touche moi je tempoisonne !"
}, },
"MONO_GROUND": { "MONO_GROUND": {
"name": "Prévisions : Séisme" "name": "Prévisions : Séisme"
@ -242,7 +242,7 @@
"name": "SOS Fantômes" "name": "SOS Fantômes"
}, },
"MONO_STEEL": { "MONO_STEEL": {
"name": "De type Acier !" "name": "De type Acier !"
}, },
"MONO_FIRE": { "MONO_FIRE": {
"name": "Allumer le feu" "name": "Allumer le feu"

View File

@ -36,5 +36,6 @@
"matBlock": "Tatamigaeshi", "matBlock": "Tatamigaeshi",
"craftyShield": "Vigilance", "craftyShield": "Vigilance",
"tailwind": "Vent Arrière", "tailwind": "Vent Arrière",
"happyHour": "Étrennes" "happyHour": "Étrennes",
"safeguard": "Rune Protect"
} }

View File

@ -1,70 +1,71 @@
{ {
"bossAppeared": "Un {{bossName}} apparait.", "bossAppeared": "Un {{bossName}} apparait.",
"trainerAppeared": "Un combat est lancé\npar {{trainerName}} !", "trainerAppeared": "Un combat est lancé\npar {{trainerName}} !",
"trainerAppearedDouble": "Un combat est lancé\npar {{trainerName}} !", "trainerAppearedDouble": "Un combat est lancé\npar {{trainerName}} !",
"trainerSendOut": "{{pokemonName}} est envoyé par\n{{trainerName}} !", "trainerSendOut": "{{pokemonName}} est envoyé par\n{{trainerName}} !",
"singleWildAppeared": "Un {{pokemonName}} sauvage apparait !", "singleWildAppeared": "Un {{pokemonName}} sauvage apparait !",
"multiWildAppeared": "Un {{pokemonName1}} et un {{pokemonName2}}\nsauvages apparaissent !", "multiWildAppeared": "Un {{pokemonName1}} et un {{pokemonName2}}\nsauvages apparaissent !",
"playerComeBack": "{{pokemonName}} !\nReviens !", "playerComeBack": "{{pokemonName}} !\nReviens !",
"trainerComeBack": "{{trainerName}} retire {{pokemonName}} !", "trainerComeBack": "{{trainerName}} retire\n{{pokemonName}} !",
"playerGo": "{{pokemonName}} ! Go !", "playerGo": "{{pokemonName}} ! Go !",
"trainerGo": "{{pokemonName}} est envoyé par\n{{trainerName}} !", "trainerGo": "{{pokemonName}} est envoyé par\n{{trainerName}} !",
"switchQuestion": "Voulez-vous changer\nvotre {{pokemonName}} ?", "switchQuestion": "Voulez-vous changer\n{{pokemonName}} ?",
"trainerDefeated": "Vous avez battu\n{{trainerName}} !", "trainerDefeated": "Vous avez battu\n{{trainerName}} !",
"moneyWon": "Vous remportez\n{{moneyAmount}} ₽ !", "moneyWon": "Vous remportez\n{{moneyAmount}} ₽ !",
"moneyPickedUp": "Vous obtenez {{moneyAmount}} ₽ !", "moneyPickedUp": "Vous obtenez {{moneyAmount}} ₽ !",
"pokemonCaught": "Vous avez attrapé {{pokemonName}} !", "pokemonCaught": "Vous avez attrapé\n{{pokemonName}} !",
"addedAsAStarter": "{{pokemonName}} est ajouté\ncomme starter !", "addedAsAStarter": "{{pokemonName}} est ajouté\ncomme starter !",
"partyFull": "Votre équipe est pleine.\nRelâcher un Pokémon pour {{pokemonName}} ?", "partyFull": "Votre équipe est pleine.\nRelâcher un Pokémon pour {{pokemonName}} ?",
"pokemon": "Pokémon", "pokemon": "de Pokémon",
"sendOutPokemon": "{{pokemonName}} ! Go !", "sendOutPokemon": "{{pokemonName}} ! Go !",
"hitResultCriticalHit": "Coup critique !", "hitResultCriticalHit": "Coup critique !",
"hitResultSuperEffective": "Cest super efficace !", "hitResultSuperEffective": "Cest super efficace !",
"hitResultNotVeryEffective": "Ce nest pas très efficace…", "hitResultNotVeryEffective": "Ce nest pas très efficace…",
"hitResultNoEffect": "Ça naffecte pas {{pokemonName}}…", "hitResultNoEffect": "Ça naffecte pas {{pokemonName}}…",
"hitResultImmune": "{{pokemonName}} nest pas affecté !", "hitResultImmune": "{{pokemonName}} nest pas affecté !",
"hitResultOneHitKO": "K.O. en un coup !", "hitResultOneHitKO": "K.O. en un coup !",
"attackFailed": "Mais cela échoue !", "attackFailed": "Mais cela échoue !",
"attackMissed": "{{pokemonNameWithAffix}}\névite lattaque!", "attackMissed": "{{pokemonNameWithAffix}}\névite lattaque!",
"attackHitsCount": "Touché {{count}} fois !", "attackHitsCount": "Touché {{count}} fois !",
"rewardGain": "Vous recevez\n{{modifierName}} !", "rewardGain": "Vous recevez\n{{modifierName}} !",
"expGain": "{{pokemonName}} gagne\n{{exp}} Points dExp !", "expGain": "{{pokemonName}} gagne\n{{exp}} Points dExp !",
"levelUp": "{{pokemonName}} monte au\nN. {{level}} !", "levelUp": "{{pokemonName}} monte au\nN. {{level}} !",
"learnMove": "{{pokemonName}} apprend\n{{moveName}} !", "learnMove": "{{pokemonName}} apprend\n{{moveName}} !",
"learnMovePrompt": "{{pokemonName}} veut apprendre\n{{moveName}}.", "learnMovePrompt": "{{pokemonName}} veut apprendre\n{{moveName}}.",
"learnMoveLimitReached": "Cependant, {{pokemonName}} connait\ndéjà quatre capacités.", "learnMoveLimitReached": "Cependant, {{pokemonName}} connait\ndéjà quatre capacités.",
"learnMoveReplaceQuestion": "Voulez-vous oublier une capacité\net la remplacer par {{moveName}} ?", "learnMoveReplaceQuestion": "Voulez-vous oublier une capacité\net la remplacer par {{moveName}} ?",
"learnMoveStopTeaching": "Arrêter dapprendre\n{{moveName}} ?", "learnMoveStopTeaching": "Arrêter dapprendre\n{{moveName}} ?",
"learnMoveNotLearned": "{{pokemonName}} na pas appris\n{{moveName}}.", "learnMoveNotLearned": "{{pokemonName}} na pas appris\n{{moveName}}.",
"learnMoveForgetQuestion": "Quelle capacité doit être oubliée ?", "learnMoveForgetQuestion": "Quelle capacité doit être oubliée ?",
"learnMoveForgetSuccess": "{{pokemonName}} oublie comment\nutiliser {{moveName}}.", "learnMoveForgetSuccess": "{{pokemonName}} oublie comment\nutiliser {{moveName}}.",
"countdownPoof": "@d{32}1, @d{15}2, @d{15}et@d{15}… @d{15}… @d{15}… @d{15}@s{se/pb_bounce_1}Tadaaa !", "countdownPoof": "@d{32}1, @d{15}2, @d{15}et@d{15}… @d{15}… @d{15}… @d{15}@s{se/pb_bounce_1}Tadaaa !",
"learnMoveAnd": "Et…", "learnMoveAnd": "Et…",
"levelCapUp": "La limite de niveau\na été augmentée à {{levelCap}} !", "levelCapUp": "La limite de niveau\na été augmentée à {{levelCap}} !",
"moveNotImplemented": "{{moveName}} nest pas encore implémenté et ne peut pas être sélectionné.", "moveNotImplemented": "{{moveName}} nest pas encore implémenté et ne peut pas être sélectionné.",
"moveNoPP": "Il ny a plus de PP pour\ncette capacité !", "moveNoPP": "Il ny a plus de PP pour\ncette capacité !",
"moveDisabled": "{{moveName}} est sous entrave !", "moveDisabled": "{{moveName}} est sous entrave !",
"disableInterruptedMove": "Il y a une entrave sur la capacité {{moveName}}\nde{{pokemonNameWithAffix}} !",
"noPokeballForce": "Une force mystérieuse\nempêche lutilisation des Poké Balls.", "noPokeballForce": "Une force mystérieuse\nempêche lutilisation des Poké Balls.",
"noPokeballTrainer": "Le Dresseur détourne la Ball\nVoler, cest mal !", "noPokeballTrainer": "Le Dresseur détourne la Ball\nVoler, cest mal !",
"noPokeballMulti": "Impossible ! On ne peut pas viser\nquand il y a deux Pokémon !", "noPokeballMulti": "Impossible ! On ne peut pas viser\nquand il y a deux Pokémon !",
"noPokeballStrong": "Le Pokémon est trop fort pour être capturé !\nVous devez dabord laffaiblir !", "noPokeballStrong": "Le Pokémon est trop fort pour être capturé !\nVous devez dabord laffaiblir !",
"noEscapeForce": "Une force mystérieuse\nempêche la fuite.", "noEscapeForce": "Une force mystérieuse\nempêche la fuite.",
"noEscapeTrainer": "On ne senfuit pas dun\ncombat de Dresseurs !", "noEscapeTrainer": "On ne senfuit pas dun\ncombat de Dresseurs !",
"noEscapePokemon": "{{moveName}} de {{pokemonName}}\nempêche {{escapeVerb}} !", "noEscapePokemon": "{{moveName}} de {{pokemonName}}\nempêche {{escapeVerb}} !",
"runAwaySuccess": "Vous prenez la fuite !", "runAwaySuccess": "Vous prenez la fuite !",
"runAwayCannotEscape": "Fuite impossible !", "runAwayCannotEscape": "Fuite impossible !",
"escapeVerbSwitch": "le changement", "escapeVerbSwitch": "le changement",
"escapeVerbFlee": "la fuite", "escapeVerbFlee": "la fuite",
"notDisabled": "La capacité {{moveName}}\nde {{pokemonName}} nest plus sous entrave !", "notDisabled": "La capacité {{moveName}}\nde {{pokemonName}} nest plus sous entrave !",
"turnEndHpRestore": "{{pokemonName}} récupère des PV !", "turnEndHpRestore": "{{pokemonName}} récupère des PV !",
"hpIsFull": "Les PV de {{pokemonName}}\nsont au maximum !", "hpIsFull": "Les PV de {{pokemonName}}\nsont au maximum !",
"skipItemQuestion": "Êtes-vous sûr·e de ne pas vouloir prendre dobjet ?", "skipItemQuestion": "Êtes-vous sûr·e de ne pas vouloir prendre dobjet ?",
"itemStackFull": "Quantité maximale de {{fullItemName}} atteinte.\nVous recevez {{itemName}} à la place.", "itemStackFull": "Quantité maximale de {{fullItemName}} atteinte.\nVous recevez {{itemName}} à la place.",
"eggHatching": "Hein ?", "eggHatching": "Hein ?",
"ivScannerUseQuestion": "Utiliser le Scanner dIV\nsur {{pokemonName}} ?", "ivScannerUseQuestion": "Utiliser le Scanner dIV\nsur {{pokemonName}} ?",
"wildPokemonWithAffix": "{{pokemonName}} sauvage", "wildPokemonWithAffix": "{{pokemonName}} sauvage",
"foePokemonWithAffix": "{{pokemonName}} ennemi", "foePokemonWithAffix": "{{pokemonName}} ennemi",
"useMove": "{{pokemonNameWithAffix}} utilise\n{{moveName}} !", "useMove": "{{pokemonNameWithAffix}} utilise\n{{moveName}} !",
"stealEatBerry": "{{pokemonName}} vole et mange\nla {{berryName}} de {{targetName}} !", "stealEatBerry": "{{pokemonName}} vole et mange\nla {{berryName}} de {{targetName}} !",
"ppHealBerry": "La {{berryName}} de {{pokemonNameWithAffix}}\nrestaure les PP de sa capacité {{moveName}} !", "ppHealBerry": "La {{berryName}} de {{pokemonNameWithAffix}}\nrestaure les PP de sa capacité {{moveName}} !",
"hpHealBerry": "La {{berryName}} de {{pokemonNameWithAffix}}\nrestaure son énergie !", "hpHealBerry": "La {{berryName}} de {{pokemonNameWithAffix}}\nrestaure son énergie !",
@ -73,27 +74,27 @@
"fainted": "{{pokemonNameWithAffix}}\nest K.O. !", "fainted": "{{pokemonNameWithAffix}}\nest K.O. !",
"statsAnd": "et", "statsAnd": "et",
"stats": "Les stats", "stats": "Les stats",
"statRose_one": "{{stats}} de {{pokemonNameWithAffix}}\naugmente !", "statRose_one": "{{stats}} de {{pokemonNameWithAffix}}\naugmente !",
"statRose_other": "{{stats}}\nde {{pokemonNameWithAffix}} augmentent !", "statRose_other": "{{stats}}\nde {{pokemonNameWithAffix}} augmentent !",
"statSharplyRose_one": "{{stats}} de {{pokemonNameWithAffix}}\naugmente beaucoup !", "statSharplyRose_one": "{{stats}} de {{pokemonNameWithAffix}}\naugmente beaucoup !",
"statSharplyRose_other": "{{stats}}\nde {{pokemonNameWithAffix}} augmentent beaucoup !", "statSharplyRose_other": "{{stats}}\nde {{pokemonNameWithAffix}} augmentent beaucoup !",
"statRoseDrastically_one": "{{stats}} de {{pokemonNameWithAffix}}\naugmente énormément !", "statRoseDrastically_one": "{{stats}} de {{pokemonNameWithAffix}}\naugmente énormément !",
"statRoseDrastically_other": "{{stats}}\nde {{pokemonNameWithAffix}} augmentent énormément !", "statRoseDrastically_other": "{{stats}}\nde {{pokemonNameWithAffix}} augmentent énormément !",
"statWontGoAnyHigher_one": "{{stats}} de {{pokemonNameWithAffix}}\nne peut plus augmenter !", "statWontGoAnyHigher_one": "{{stats}} de {{pokemonNameWithAffix}}\nne peut plus augmenter !",
"statWontGoAnyHigher_other": "{{stats}}\nde {{pokemonNameWithAffix}} ne peuvent plus augmenter !", "statWontGoAnyHigher_other": "{{stats}}\nde {{pokemonNameWithAffix}} ne peuvent plus augmenter !",
"statFell_one": "{{stats}} de {{pokemonNameWithAffix}}\nbaisse !", "statFell_one": "{{stats}} de {{pokemonNameWithAffix}}\nbaisse !",
"statFell_other": "{{stats}}\nde {{pokemonNameWithAffix}} baissent !", "statFell_other": "{{stats}}\nde {{pokemonNameWithAffix}} baissent !",
"statHarshlyFell_one": "{{stats}} de {{pokemonNameWithAffix}}\nbaisse beaucoup !", "statHarshlyFell_one": "{{stats}} de {{pokemonNameWithAffix}}\nbaisse beaucoup !",
"statHarshlyFell_other": "{{stats}}\nde {{pokemonNameWithAffix}} baissent beaucoup !", "statHarshlyFell_other": "{{stats}}\nde {{pokemonNameWithAffix}} baissent beaucoup !",
"statSeverelyFell_one": "{{stats}} de {{pokemonNameWithAffix}}\nbaisse énormément !", "statSeverelyFell_one": "{{stats}} de {{pokemonNameWithAffix}}\nbaisse énormément !",
"statSeverelyFell_other": "{{stats}}\nde {{pokemonNameWithAffix}} baissent énormément !", "statSeverelyFell_other": "{{stats}}\nde {{pokemonNameWithAffix}} baissent énormément !",
"statWontGoAnyLower_one": "{{stats}} de {{pokemonNameWithAffix}}\nne peut plus baisser !", "statWontGoAnyLower_one": "{{stats}} de {{pokemonNameWithAffix}}\nne peut plus baisser !",
"statWontGoAnyLower_other": "{{stats}}\nde {{pokemonNameWithAffix}} ne peuvent plus baisser !", "statWontGoAnyLower_other": "{{stats}}\nde {{pokemonNameWithAffix}} ne peuvent plus baisser !",
"transformedIntoType": "{{pokemonName}} transformed\ninto the {{type}} type!", "transformedIntoType": "{{pokemonName}} prend\nle type {{type}} !",
"ppReduced": "Les PP de la capacité {{moveName}}\nde {{targetName}} baissent de {{reduction}} !", "ppReduced": "Les PP de la capacité {{moveName}}\nde {{targetName}} baissent de {{reduction}} !",
"retryBattle": "Voulez-vous réessayer depuis le début du combat ?", "retryBattle": "Voulez-vous réessayer depuis le début du combat ?",
"unlockedSomething": "{{unlockedThing}}\na été débloqué.", "unlockedSomething": "{{unlockedThing}}\na été débloqué.",
"congratulations": "Félicitations !", "congratulations": "Félicitations !",
"beatModeFirstTime": "{{speciesName}} a battu le mode {{gameMode}} pour la première fois !\nVous avez reçu {{newModifier}} !", "beatModeFirstTime": "{{speciesName}} a battu le mode {{gameMode}} pour la première fois !\nVous avez reçu {{newModifier}} !",
"eggSkipPrompt": "Aller directement au résumé des Œufs éclos ?" "eggSkipPrompt": "Aller directement au résumé des Œufs éclos ?"
} }

View File

@ -29,8 +29,8 @@
"nightmareOnAdd": "{{pokemonNameWithAffix}} commence à cauchemarder !", "nightmareOnAdd": "{{pokemonNameWithAffix}} commence à cauchemarder !",
"nightmareOnOverlap": "{{pokemonNameWithAffix}} est\ndéjà prisonnier dun cauchemar !", "nightmareOnOverlap": "{{pokemonNameWithAffix}} est\ndéjà prisonnier dun cauchemar !",
"nightmareLapse": "{{pokemonNameWithAffix}}est\nprisonnier dun cauchemar !", "nightmareLapse": "{{pokemonNameWithAffix}}est\nprisonnier dun cauchemar !",
"encoreOnAdd": "{{pokemonNameWithAffix}} !\nEncore une fois !", "encoreOnAdd": "{{pokemonNameWithAffix}} !\nEncore une fois !",
"encoreOnRemove": "{{pokemonNameWithAffix}} nest\nplus obligé dutiliser la même capacité !", "encoreOnRemove": "{{pokemonNameWithAffix}} nest\nplus obligé dutiliser la même capacité !",
"helpingHandOnAdd": "{{pokemonNameWithAffix}} est prêt\nà aider {{pokemonName}} !", "helpingHandOnAdd": "{{pokemonNameWithAffix}} est prêt\nà aider {{pokemonName}} !",
"ingrainLapse": "{{pokemonNameWithAffix}} absorbe\ndes nutriments avec ses racines !", "ingrainLapse": "{{pokemonNameWithAffix}} absorbe\ndes nutriments avec ses racines !",
"ingrainOnTrap": "{{pokemonNameWithAffix}}\nplante ses racines !", "ingrainOnTrap": "{{pokemonNameWithAffix}}\nplante ses racines !",
@ -50,22 +50,24 @@
"protectedOnAdd": "{{pokemonNameWithAffix}}\nest prêt à se protéger !", "protectedOnAdd": "{{pokemonNameWithAffix}}\nest prêt à se protéger !",
"protectedLapse": "{{pokemonNameWithAffix}}\nse protège !", "protectedLapse": "{{pokemonNameWithAffix}}\nse protège !",
"enduringOnAdd": "{{pokemonNameWithAffix}} se prépare\nà encaisser les coups !", "enduringOnAdd": "{{pokemonNameWithAffix}} se prépare\nà encaisser les coups !",
"enduringLapse": "{{pokemonNameWithAffix}}\nencaisse les coups !", "enduringLapse": "{{pokemonNameWithAffix}}\nencaisse les coups !",
"sturdyLapse": "{{pokemonNameWithAffix}}\nencaisse les coups !", "sturdyLapse": "{{pokemonNameWithAffix}}\nencaisse les coups !",
"perishSongLapse": "Le compte à rebours de Requiem\nde {{pokemonNameWithAffix}} descend à {{turnCount}} !", "perishSongLapse": "Le compte à rebours de Requiem\nde {{pokemonNameWithAffix}} descend à {{turnCount}} !",
"centerOfAttentionOnAdd": "{{pokemonNameWithAffix}} devient\nle centre de lattention !", "centerOfAttentionOnAdd": "{{pokemonNameWithAffix}} devient\nle centre de lattention !",
"truantLapse": "{{pokemonNameWithAffix}} paresse !", "truantLapse": "{{pokemonNameWithAffix}} paresse !",
"slowStartOnAdd": "{{pokemonNameWithAffix}}\nnarrive pas à se motiver !", "slowStartOnAdd": "{{pokemonNameWithAffix}}\nnarrive pas à se motiver !",
"slowStartOnRemove": "{{pokemonNameWithAffix}}\narrive enfin à sy mettre sérieusement !", "slowStartOnRemove": "{{pokemonNameWithAffix}}\narrive enfin à sy mettre sérieusement !",
"highestStatBoostOnAdd": "{{statName}} de {{pokemonNameWithAffix}}\nest renforcée !", "highestStatBoostOnAdd": "{{statName}} de {{pokemonNameWithAffix}}\nest renforcée !",
"highestStatBoostOnRemove": "Leffet du talent {{abilityName}}\nde {{pokemonNameWithAffix}} se dissipe !", "highestStatBoostOnRemove": "Leffet du talent {{abilityName}}\nde {{pokemonNameWithAffix}} se dissipe !",
"magnetRisenOnAdd": "{{pokemonNameWithAffix}} lévite\nsur un champ magnétique !", "magnetRisenOnAdd": "{{pokemonNameWithAffix}} lévite\nsur un champ magnétique !",
"magnetRisenOnRemove": "Le magnétisme de{{pokemonNameWithAffix}}\nse dissipe !", "magnetRisenOnRemove": "Le magnétisme de{{pokemonNameWithAffix}}\nse dissipe !",
"critBoostOnAdd": "{{pokemonNameWithAffix}}\nest prêt à tout donner !", "critBoostOnAdd": "{{pokemonNameWithAffix}}\nest prêt à tout donner !",
"critBoostOnRemove": "{{pokemonNameWithAffix}} se détend.", "critBoostOnRemove": "{{pokemonNameWithAffix}} se détend.",
"saltCuredOnAdd": "{{pokemonNameWithAffix}}\nest couvert de sel !", "saltCuredOnAdd": "{{pokemonNameWithAffix}}\nest couvert de sel !",
"saltCuredLapse": "{{pokemonNameWithAffix}} est blessé\npar la capacité {{moveName}} !", "saltCuredLapse": "{{pokemonNameWithAffix}} est blessé\npar la capacité {{moveName}} !",
"cursedOnAdd": "{{pokemonNameWithAffix}} sacrifie des PV\net lance une malédiction sur {{pokemonName}} !", "cursedOnAdd": "{{pokemonNameWithAffix}} sacrifie des PV\net lance une malédiction sur {{pokemonName}} !",
"cursedLapse": "{{pokemonNameWithAffix}} est touché par la malédiction !", "cursedLapse": "{{pokemonNameWithAffix}} est touché par la malédiction !",
"stockpilingOnAdd": "{{pokemonNameWithAffix}} utilise\nla capacité Stockage {{stockpiledCount}} fois !" "stockpilingOnAdd": "{{pokemonNameWithAffix}} utilise\nla capacité Stockage {{stockpiledCount}} fois !",
"disabledOnAdd": "La capacité {{moveName}}\nde {{pokemonNameWithAffix}} est mise sous entrave !",
"disabledLapse": "La capacité {{moveName}}\nde {{pokemonNameWithAffix}} nest plus sous entrave !"
} }

View File

@ -3,5 +3,5 @@
"ball": "Ball", "ball": "Ball",
"pokemon": "Pokémon", "pokemon": "Pokémon",
"run": "Fuite", "run": "Fuite",
"actionMessage": "Que doit faire\n{{pokemonName}} ?" "actionMessage": "Que doit faire\n{{pokemonName}} ?"
} }

View File

@ -1,83 +1,83 @@
{ {
"blue_red_double": { "blue_red_double": {
"encounter": { "encounter": {
"1": "Blue : Hé Red, montrons-lui de quel bois on se chauffe !\n$Red : …\n$Blue : Voilà la puissance du Bourg Palette !" "1": "Blue : Hé Red, montrons-lui de quel bois on se chauffe !\n$Red : …\n$Blue : Voilà la puissance du Bourg Palette !"
}, },
"victory": { "victory": {
"1": "Blue : Cétait un magnifique combat !\n$Red : …" "1": "Blue : Cétait un magnifique combat !\n$Red : …"
} }
}, },
"red_blue_double": { "red_blue_double": {
"encounter": { "encounter": {
"1": "Red : … !\n$Blue : Il est pas très loquace.\n$Blue : Mais ne te laisse pas avoir, ça reste un Maitre Pokémon !" "1": "Red : … !\n$Blue : Il est pas très loquace.\n$Blue : Mais ne te laisse pas avoir, ça reste un Maitre Pokémon !"
}, },
"victory": { "victory": {
"1": "Red : … !\n$Blue : La prochaine fois, on va te battre !" "1": "Red : … !\n$Blue : La prochaine fois, on va te battre !"
} }
}, },
"tate_liza_double": { "tate_liza_double": {
"encounter": { "encounter": {
"1": "Lévy : Héhéhé… Tu en fais une drôle de tête.\n$Tatia : Tu ne tattendais pas à rencontrer deux Champions, nest-ce pas ?\n$Lévy : Nous sommes des jumeaux !\n$Tatia : Nous navons pas besoin de parler entre nous !\n$Lévy : Tu crois pouvoir briser…\n$Tatia : … Notre duo parfait ?" "1": "Lévy : Héhéhé… Tu en fais une drôle de tête.\n$Tatia : Tu ne tattendais pas à rencontrer deux Champions, nest-ce pas ?\n$Lévy : Nous sommes des jumeaux !\n$Tatia : Nous navons pas besoin de parler entre nous !\n$Lévy : Tu crois pouvoir briser…\n$Tatia : … Notre duo parfait ?"
}, },
"victory": { "victory": {
"1": "Lévy : Quoi ? Notre combinaison était parfaite !\n$Tatia : Nous avons encore besoin dentrainement…" "1": "Lévy : Quoi ? Notre combinaison était parfaite !\n$Tatia : Nous avons encore besoin dentrainement…"
} }
}, },
"liza_tate_double": { "liza_tate_double": {
"encounter": { "encounter": {
"1": "Tatia : Hihih… Si tu voyais ta tête !\n$Lévy : Oui, nous sommes deux Champions en un !\n$Tatia : Voici mon frère, Lévy…\n$Lévy : … Et ma sœur, Tatia !\n$Tatia : Tu ne penses pas que notre combinaison est parfaite ?" "1": "Tatia : Hihih… Si tu voyais ta tête !\n$Lévy : Oui, nous sommes deux Champions en un !\n$Tatia : Voici mon frère, Lévy…\n$Lévy : … Et ma sœur, Tatia !\n$Tatia : Tu ne penses pas que notre combinaison est parfaite ?"
}, },
"victory": { "victory": {
"1": "Tatia : Quoi ? Notre combinaison…\n$Lévy : … a échoué !" "1": "Tatia : Quoi ? Notre combinaison…\n$Lévy : … a échoué !"
} }
}, },
"wallace_steven_double": { "wallace_steven_double": {
"encounter": { "encounter": {
"1": "Pierre R. : Marc, montrons-lui la puissance des Maitres !\n$Marc : Tu vas gouter au pouvoir de Hoenn !\n$Pierre R. : Cest parti !" "1": "Pierre R. : Marc, montrons-lui la puissance des Maitres !\n$Marc : Tu vas gouter au pouvoir de Hoenn !\n$Pierre R. : Cest parti !"
}, },
"victory": { "victory": {
"1": "Pierre R. : Cétait un beau combat !\n$Marc : Ce sera notre tour la prochaine fois !" "1": "Pierre R. : Cétait un beau combat !\n$Marc : Ce sera notre tour la prochaine fois !"
} }
}, },
"steven_wallace_double": { "steven_wallace_double": {
"encounter": { "encounter": {
"1": "Pierre R. : Excuse-moi, aurais-tu des Pokémon rares ?\n$Marc : Pierre… Nous sommes là pour nous battre, pas pour frimer avec nos Pokémon.\n$Pierre R. : Oh… Je vois… Commençons alors !" "1": "Pierre R. : Excuse-moi, aurais-tu des Pokémon rares ?\n$Marc : Pierre… Nous sommes là pour nous battre, pas pour frimer avec nos Pokémon.\n$Pierre R. : Oh… Je vois… Commençons alors !"
}, },
"victory": { "victory": {
"1": "Pierre R. : Bien, maintenant que ce combat est clos, montrons-nous nos Pokémon !\n$Marc : Pierre…" "1": "Pierre R. : Bien, maintenant que ce combat est clos, montrons-nous nos Pokémon !\n$Marc : Pierre…"
} }
}, },
"alder_iris_double": { "alder_iris_double": {
"encounter": { "encounter": {
"1": "Goyah : Nous sommes lélite des Dresseurs dUnys !\n$Iris : Rien de mieux que des combats contre des prodiges !" "1": "Goyah : Nous sommes lélite des Dresseurs dUnys !\n$Iris : Rien de mieux que des combats contre des prodiges !"
}, },
"victory": { "victory": {
"1": "Goyah : INCROYABLE ! Tes trop doué !\n$Iris : On gagnera la prochaine fois !" "1": "Goyah : INCROYABLE ! Tes trop doué !\n$Iris : On gagnera la prochaine fois !"
} }
}, },
"iris_alder_double": { "iris_alder_double": {
"encounter": { "encounter": {
"1": "Iris : Bienvenue, Dresseur ! Je suis LA Maitresse dUnys !\n$Goyah : Iris, concentre-toi sil te plait…" "1": "Iris : Bienvenue, Dresseur ! Je suis LA Maitresse dUnys !\n$Goyah : Iris, concentre-toi sil te plait…"
}, },
"victory": { "victory": {
"1": "Iris : On a tout donné et pourtant…\n$Goyah : Cette défaite ne pourra que nous être bénéfique !" "1": "Iris : On a tout donné et pourtant…\n$Goyah : Cette défaite ne pourra que nous être bénéfique !"
} }
}, },
"piers_marnie_double": { "piers_marnie_double": {
"encounter": { "encounter": {
"1": "Rosemary : Frérot, montrons-lui la puissance de Smashings !\n$Peterson : Nous sommes les ténèbres !" "1": "Rosemary : Frérot, montrons-lui la puissance de Smashings !\n$Peterson : Nous sommes les ténèbres !"
}, },
"victory": { "victory": {
"1": "Rosemary : Tas amené la lumière dans les ténèbres !\n$Peterson : Ptêtre un peu trop…" "1": "Rosemary : Tas amené la lumière dans les ténèbres !\n$Peterson : Ptêtre un peu trop…"
} }
}, },
"marnie_piers_double": { "marnie_piers_double": {
"encounter": { "encounter": {
"1": "Peterson : Chauds pour un concert ?\n$Rosemary : Frérot… Il est pas là pour chanter, mais se battre…", "1": "Peterson : Chauds pour un concert ?\n$Rosemary : Frérot… Il est pas là pour chanter, mais se battre…",
"1_female": "Peterson : Chauds pour un concert ?\n$Rosemary : Frérot… Elle est pas là pour chanter, mais se battre…" "1_female": "Peterson : Chauds pour un concert ?\n$Rosemary : Frérot… Elle est pas là pour chanter, mais se battre…"
}, },
"victory": { "victory": {
"1": "Peterson : Ça cest du rock !\n$Rosemary : Frérot…" "1": "Peterson : Ça cest du rock !\n$Rosemary : Frérot…"
} }
} }
} }

View File

@ -1,6 +1,6 @@
{ {
"encounter": "Une fois de plus, te revoilà.\nSais-tu que ce nest point là ta première venue ?\n$Tu as été appelé ici parce que ty es déjà venu.\nUn nombre inimaginable de fois.\n$Mais allons-y, faisons le décompte.\nTu en es très précisément à ton {{cycleCount}}e cycle.\n$Chaque cycle réinitialise ton souvenir du précédent.\nMais étrangement, des bribes subsistent en toi.\n$Jusquà maintenant, tu as toujours échoué. Mais je ressens quelque chose de différent cette fois-ci.\n\n$Tu es la seule présence ici, bien que jai le sentiment den ressentir… une autre.\n$Vas-tu enfin me livrer un affrontement digne de ce nom ?\nCe challenge dont je rêve depuis un millénaire ?\n$Commençons.", "encounter": "Une fois de plus, te revoilà.\nSais-tu que ce nest point là ta première venue ?\n$Tu as été appelé ici parce que ty es déjà venu.\nUn nombre inimaginable de fois.\n$Mais allons-y, faisons le décompte.\nTu en es très précisément à ton {{cycleCount}}e cycle.\n$Chaque cycle réinitialise ton souvenir du précédent.\nMais étrangement, des bribes subsistent en toi.\n$Jusquà maintenant, tu as toujours échoué. Mais je ressens quelque chose de différent cette fois-ci.\n\n$Tu es la seule présence ici, bien que jai le sentiment den ressentir… une autre.\n$Vas-tu enfin me livrer un affrontement digne de ce nom ?\nCe challenge dont je rêve depuis un millénaire ?\n$Commençons.",
"encounter_female": "Une fois de plus, te revoilà.\nSais-tu que ce nest point là ta première venue ?\n$Tu as été appelée ici parce que ty es déjà venue.\nUn nombre inimaginable de fois.\n$Mais allons-y, faisons le décompte.\nTu en es très précisément à ton {{cycleCount}}e cycle.\n$Chaque cycle réinitialise ton souvenir du précédent.\nMais étrangement, des bribes subsistent en toi.\n$Jusquà maintenant, tu as toujours échoué. Mais je ressens quelque chose de différent cette fois-ci.\n\n$Tu es la seule présence ici, bien que jai le sentiment den ressentir… une autre.\n$Vas-tu enfin me livrer un affrontement digne de ce nom ?\nCe challenge dont je rêve depuis un millénaire ?\n$Commençons.", "encounter_female": "Une fois de plus, te revoilà.\nSais-tu que ce nest point là ta première venue ?\n$Tu as été appelée ici parce que ty es déjà venue.\nUn nombre inimaginable de fois.\n$Mais allons-y, faisons le décompte.\nTu en es très précisément à ton {{cycleCount}}e cycle.\n$Chaque cycle réinitialise ton souvenir du précédent.\nMais étrangement, des bribes subsistent en toi.\n$Jusquà maintenant, tu as toujours échoué. Mais je ressens quelque chose de différent cette fois-ci.\n\n$Tu es la seule présence ici, bien que jai le sentiment den ressentir… une autre.\n$Vas-tu enfin me livrer un affrontement digne de ce nom ?\nCe challenge dont je rêve depuis un millénaire ?\n$Commençons.",
"firstStageWin": "Je vois. Cette présence était bien réelle.\nJe nai donc plus besoin de retenir mes coups.\n$Ne me déçoit pas.", "firstStageWin": "Je vois. Cette présence était bien réelle.\nJe nai donc plus besoin de retenir mes coups.\n$Ne me déçoit pas.",
"secondStageWin": "… Magnifique." "secondStageWin": "… Magnifique."
} }

View File

@ -1,6 +1,6 @@
{ {
"ending": "@c{shock}Tes revenu ?@d{32} Ça veut dire…@d{96} que tas gagné ?!\n@c{smile_ehalf}Jaurais dû men douter.\n$@c{smile_eclosed}Bien sûr… Jai toujours eu ce sentiment.\n@c{smile}Cest fini maintenant hein ? Tas brisé ce cycle.\n$@c{smile_ehalf}Tas aussi accompli ton rêve non ?\nTu nas pas connu la moindre défaite.\n$Je serai la seule à me souvenir de ce que tas fait.\n@c{angry_mopen}Je tâcherai de ne pas oublier !\n$@c{smile_wave_wink}Jdéconne !@d{64} @c{smile}Jamais joublierai.@d{32}\nTa légende vivra à jamais dans nos cœurs.\n$@c{smile_wave}Bon,@d{64} il se fait tard…@d{96} je crois ?\nDifficile à dire ici.\n$Rentrons, @c{smile_wave_wink}et demain on se fera un ptit combat, comme au bon vieux temps ?", "ending": "@c{shock}Tes revenu ?@d{32} Ça veut dire…@d{96} que tas gagné ?!\n@c{smile_ehalf}Jaurais dû men douter.\n$@c{smile_eclosed}Bien sûr… Jai toujours eu ce sentiment.\n@c{smile}Cest fini maintenant hein ? Tas brisé ce cycle.\n$@c{smile_ehalf}Tas aussi accompli ton rêve non ?\nTu nas pas connu la moindre défaite.\n$Je serai la seule à me souvenir de ce que tas fait.\n@c{angry_mopen}Je tâcherai de ne pas oublier !\n$@c{smile_wave_wink}Jdéconne !@d{64} @c{smile}Jamais joublierai.@d{32}\nTa légende vivra à jamais dans nos cœurs.\n$@c{smile_wave}Bon,@d{64} il se fait tard…@d{96} je crois ?\nDifficile à dire ici.\n$Rentrons, @c{smile_wave_wink}et demain on se fera un ptit combat, comme au bon vieux temps ?",
"ending_female": "@c{smile}Oh ? Tas gagné ?@d{96} @c{smile_eclosed}Jaurais dû men douter.\nMais te voilà enfin de retour.\n$@c{smile}Cest terminé.@d{64} Tas brisé ce cycle infernal.\n$@c{serious_smile_fists}Tas aussi accompli ton rêve non ?\nTu nas pas connu la moindre défaite.\n$@c{neutral}Je suis le seul à me souvenir de ce que tas fait.@d{96}\nJe pense que ça ira, non ?\n$@c{serious_smile_fists}Ta légende vivra à jamais dans nos cœurs.\n$@c{smile_eclosed}Bref, jen ai un peu marre de ce endroit, pas toi ? Rentrons à la maison.\n$@c{serious_smile_fists}On se fera un ptit combat une fois rentrés ?\nSi tes daccord.", "ending_female": "@c{smile}Oh ? Tas gagné ?@d{96} @c{smile_eclosed}Jaurais dû men douter.\nMais te voilà enfin de retour.\n$@c{smile}Cest terminé.@d{64} Tas brisé ce cycle infernal.\n$@c{serious_smile_fists}Tas aussi accompli ton rêve non ?\nTu nas pas connu la moindre défaite.\n$@c{neutral}Je suis le seul à me souvenir de ce que tas fait.@d{96}\nJe pense que ça ira, non ?\n$@c{serious_smile_fists}Ta légende vivra à jamais dans nos cœurs.\n$@c{smile_eclosed}Bref, jen ai un peu marre de ce endroit, pas toi ? Rentrons à la maison.\n$@c{serious_smile_fists}On se fera un ptit combat une fois rentrés ?\nSi tes daccord.",
"ending_endless": "Félicitations ! Vous avez atteint la fin actuelle.\nPlus de contenu à venir bientôt !", "ending_endless": "Félicitations ! Vous avez atteint la fin actuelle.\nPlus de contenu à venir bientôt !",
"ending_name": "Les devs" "ending_name": "Les devs"
} }

View File

@ -1,50 +1,50 @@
{ {
"youngster": { "youngster": {
"encounter": { "encounter": {
"1": "Hé ! Combat ?", "1": "Hé ! Combat ?",
"2": "Toi aussi tu débutes ?", "2": "Toi aussi tu débutes ?",
"3": "Hé, jme souviens pas de ta tête. Combat !", "3": "Hé, jme souviens pas de ta tête. Combat !",
"4": "Jai perdu, alors jessaye de capturer dautres Pokémon.\nHé, tas lair faible toi ! Allez, combat !", "4": "Jai perdu, alors jessaye de capturer dautres Pokémon.\nHé, tas lair faible toi ! Allez, combat !",
"5": "On sconnait ? Jai comme un doute. Dans tous les cas, sympa de te rencontrer !", "5": "On sconnait ? Jai comme un doute. Dans tous les cas, sympa de te rencontrer !",
"6": "Allez, cest parti !", "6": "Allez, cest parti !",
"7": "Attention, me voilà !\nTu vas voir comment jsuis fort !", "7": "Attention, me voilà !\nTu vas voir comment jsuis fort !",
"8": "Coucou… Tu veux voir mes bô Pokémon ?", "8": "Coucou… Tu veux voir mes bô Pokémon ?",
"9": "Trêve de mondanités. Ramène-toi quand tu le sens !", "9": "Trêve de mondanités. Ramène-toi quand tu le sens !",
"10": "Baisse pas ta garde si tu veux pas pleurer davoir perdu face à un gamin.", "10": "Baisse pas ta garde si tu veux pas pleurer davoir perdu face à un gamin.",
"11": "Jai tout donné pour élever mes Pokémon. Attention à toi si tu leur fait du mal !", "11": "Jai tout donné pour élever mes Pokémon. Attention à toi si tu leur fait du mal !",
"12": "Incroyable que ty sois parvenu ! Mais la suite va pas être une partie de plaisir.", "12": "Incroyable que ty sois parvenu ! Mais la suite va pas être une partie de plaisir.",
"12_female": "Incroyable que ty sois parvenue ! Mais la suite va pas être une partie de plaisir.", "12_female": "Incroyable que ty sois parvenue ! Mais la suite va pas être une partie de plaisir.",
"13": "Les combats sont éternels ! Bienvenue dans un monde sans fin !" "13": "Les combats sont éternels ! Bienvenue dans un monde sans fin !"
}, },
"victory": { "victory": {
"1": "Hé, mais tes trop fort !", "1": "Hé, mais tes trop fort !",
"1_female": "Hé, mais tes trop forte !", "1_female": "Hé, mais tes trop forte !",
"2": "En vrai javais aucune chance hein ?", "2": "En vrai javais aucune chance hein ?",
"3": "Jte retrouverai un jour, et là jte battrai !", "3": "Jte retrouverai un jour, et là jte battrai !",
"4": "Arg… Jai plus aucun Pokémon.", "4": "Arg… Jai plus aucun Pokémon.",
"5": "Non… IMPOSSIBLE ! Pourquoi jai encore perdu…", "5": "Non… IMPOSSIBLE ! Pourquoi jai encore perdu…",
"6": "Non ! Jai perdu !", "6": "Non ! Jai perdu !",
"7": "Waah ! Tes trop incroyable ! Jsuis bouche bée !", "7": "Waah ! Tes trop incroyable ! Jsuis bouche bée !",
"8": "Pourquoi… Comment… Pourtant on est les plus forts, mes Pokémon et moi…", "8": "Pourquoi… Comment… Pourtant on est les plus forts, mes Pokémon et moi…",
"9": "Jperdrai pas la prochaine fois ! Remettons ça un jour !", "9": "Jperdrai pas la prochaine fois ! Remettons ça un jour !",
"10": "Weeeesh ! Tu vois que jsuis quun gamin ? Cest pas juste de me bully comme ça !", "10": "Weeeesh ! Tu vois que jsuis quun gamin ? Cest pas juste de me bully comme ça !",
"11": "Tes Pokémon sont trop incroyables !\n… Ptit échange ?", "11": "Tes Pokémon sont trop incroyables !\n… Ptit échange ?",
"12": "Je me suis fait un peu aider plus tôt, mais de quel taf je parlais ?", "12": "Je me suis fait un peu aider plus tôt, mais de quel taf je parlais ?",
"13": "Ahaha ! Et voilà, ça y est !\nTes déjà comme chez toi dans ce monde !" "13": "Ahaha ! Et voilà, ça y est !\nTes déjà comme chez toi dans ce monde !"
} }
}, },
"lass": { "lass": {
"encounter": { "encounter": {
"1": "Affrontons-nous, daccord ?", "1": "Affrontons-nous, daccord ?",
"2": "Tas lair dun nouveau Dresseur. Battons nous !", "2": "Tas lair dun nouveau Dresseur. Battons nous !",
"2_female": "Tas lair dune nouvelle Dresseuse. Battons nous !", "2_female": "Tas lair dune nouvelle Dresseuse. Battons nous !",
"3": "Je te connais pas. Ça te dis de te battre ?", "3": "Je te connais pas. Ça te dis de te battre ?",
"4": "Prenons du bon temps avec ce combat Pokémon !", "4": "Prenons du bon temps avec ce combat Pokémon !",
"5": "Je vais tapprendre à te battre avec tes Pokémon !", "5": "Je vais tapprendre à te battre avec tes Pokémon !",
"6": "Un combat doit toujours être pris au sérieux.\nTes prêt à te battre ?", "6": "Un combat doit toujours être pris au sérieux.\nTes prêt à te battre ?",
"6_female": "Un combat doit toujours être pris au sérieux.\nTes prête à te battre ?", "6_female": "Un combat doit toujours être pris au sérieux.\nTes prête à te battre ?",
"7": "Tu seras pas jeune éternellement. Tas quune chance pendant un combat. Bientôt, tu seras plus quun souvenir.", "7": "Tu seras pas jeune éternellement. Tas quune chance pendant un combat. Bientôt, tu seras plus quun souvenir.",
"8": "Tu ferais mieux dy aller doucement avec moi. Mais je vais me battre sérieusement !", "8": "Tu ferais mieux dy aller doucement avec moi. Mais je vais me battre sérieusement !",
"9": "Je mennuie à lécole. Ya rien à y faire. *Baille*\nJe me bats juste pour passer le temps." "9": "Je mennuie à lécole. Ya rien à y faire. *Baille*\nJe me bats juste pour passer le temps."
}, },
"victory": { "victory": {
@ -52,12 +52,12 @@
"2": "Je ne pensais pas que je perdrais comme ça…", "2": "Je ne pensais pas que je perdrais comme ça…",
"2_female": "Je pensais pas que je perdrais comme ça…", "2_female": "Je pensais pas que je perdrais comme ça…",
"3": "Jespère que jaurai ma revanche un jour.", "3": "Jespère que jaurai ma revanche un jour.",
"4": "Cétait super amusant ! Mais ce combat ma épuisée…", "4": "Cétait super amusant ! Mais ce combat ma épuisée…",
"5": "Tu mas appris une belle leçon ! Tes vraiment incroyable !", "5": "Tu mas appris une belle leçon ! Tes vraiment incroyable !",
"6": "Vraiment ? Jai perdu… ? Cest des choses qui arrivent, ça me déprime mais tu es vraiment très cool.", "6": "Vraiment ? Jai perdu… ? Cest des choses qui arrivent, ça me déprime mais tu es vraiment très cool.",
"6_female": "Vraiment ? Jai perdu… ? Cest des choses qui arrivent, ça me déprime mais tes vraiment très cool.", "6_female": "Vraiment ? Jai perdu… ? Cest des choses qui arrivent, ça me déprime mais tes vraiment très cool.",
"7": "Jai pas besoin de ce genre de souvenirs.\n*Suppression de mémoire en cours…*", "7": "Jai pas besoin de ce genre de souvenirs.\n*Suppression de mémoire en cours…*",
"8": "Hé ! Je tavais dit dy aller doucement avec moi ! Mais tes vraiment si cool quand tu te bats sérieusement…", "8": "Hé ! Je tavais dit dy aller doucement avec moi ! Mais tes vraiment si cool quand tu te bats sérieusement…",
"9": "Jen ai marre des combats Pokémon…\nJe vais chercher dautres trucs à faire…" "9": "Jen ai marre des combats Pokémon…\nJe vais chercher dautres trucs à faire…"
} }
}, },
@ -123,7 +123,7 @@
"encounter": { "encounter": {
"1": "Cest lheure de plonger dans le vif !", "1": "Cest lheure de plonger dans le vif !",
"2": "Cest le moment de surfer sur les vagues de la victoire !", "2": "Cest le moment de surfer sur les vagues de la victoire !",
"3": "Je vais téclabousser de mon talent !" "3": "Je vais téclabousser de mon talent !"
}, },
"victory": { "victory": {
"1": "Tu mas complètement séché", "1": "Tu mas complètement séché",
@ -169,10 +169,10 @@
}, },
"parasol_lady": { "parasol_lady": {
"encounter": { "encounter": {
"1": "Honorons ce terrain de combat avec élégance et équilibre !" "1": "Honorons ce terrain de combat avec élégance et équilibre !"
}, },
"victory": { "victory": {
"1": "Mon élégance demeure inébranlable !" "1": "Mon élégance demeure inébranlable !"
} }
}, },
"rocket_grunt": { "rocket_grunt": {
@ -528,14 +528,14 @@
"3": "Ouah ! Tes super balèze !" "3": "Ouah ! Tes super balèze !"
}, },
"defeat": { "defeat": {
"1": "Quen dis-tu? Cest ça, la puissance des Pokémon Eau !", "1": "Quen dis-tu ? Cest ça, la puissance des Pokémon Eau !",
"2": "Jespère que tas pris note des élégantes techniques de nage de mes Pokémon !", "2": "Jespère que tas pris note des élégantes techniques de nage de mes Pokémon !",
"3": "Tes Pokémon ne jouent visiblement pas dans le même bassin…" "3": "Tes Pokémon ne jouent visiblement pas dans le même bassin…"
} }
}, },
"lt_surge": { "lt_surge": {
"encounter": { "encounter": {
"1": "Tas pas froid aux yeux, soldat ! Les combats Pokémon, cest la guerre !", "1": "Tas pas froid aux yeux, soldat ! Les combats Pokémon, cest la guerre !",
"2": "Tu as du guts pour venir me fight ici ! Je vais te shock !", "2": "Tu as du guts pour venir me fight ici ! Je vais te shock !",
"3": "Compte tes dents, tu vas morfler !\nMes Pokémon Électrik vont tatomiser !" "3": "Compte tes dents, tu vas morfler !\nMes Pokémon Électrik vont tatomiser !"
}, },
@ -573,56 +573,56 @@
}, },
"alder": { "alder": {
"encounter": { "encounter": {
"1": "Prépare-toi pour un combat contre le meilleur Dresseur dUnys !" "1": "Prépare-toi pour un combat contre le meilleur Dresseur dUnys !"
}, },
"victory": { "victory": {
"1": "Bien joué ! Tu as sans aucun doute un talent inégalé." "1": "Bien joué ! Tu as sans aucun doute un talent inégalé."
}, },
"defeat": { "defeat": {
"1": "Une brise fraiche traverse mon cœur…\n$Quel effort extraordinaire !" "1": "Une brise fraiche traverse mon cœur…\n$Quel effort extraordinaire !"
} }
}, },
"kieran": { "kieran": {
"encounter": { "encounter": {
"1": "Grâce à un travail acharné, je deviens de plus en plus fort !\n$Je ne perdrai pas." "1": "Grâce à un travail acharné, je deviens de plus en plus fort !\n$Je ne perdrai pas."
}, },
"victory": { "victory": {
"1": "Je ny crois pas…\n$Quel combat amusant et palpitant !" "1": "Je ny crois pas…\n$Quel combat amusant et palpitant !"
}, },
"defeat": { "defeat": {
"1": "Eh beh, quel combat !\n$Il est temps pour toi de tentrainer encore plus dur." "1": "Eh beh, quel combat !\n$Il est temps pour toi de tentrainer encore plus dur."
} }
}, },
"rival": { "rival": {
"encounter": { "encounter": {
"1": "@c{smile}Ah, je te cherchais ! Je savais que tétais pressée de partir, mais je mattendais quand même à un au revoir…\n$@c{smile_eclosed}Tas finalement décidé de réaliser ton rêve ?\nJai peine à y croire.\n$@c{serious_smile_fists}Vu que tes là, ça te dis un petit combat ?\nJe voudrais quand même massurer que tes prête.\n$@c{serious_mopen_fists}Surtout ne te retiens pas et donne-moi tout ce que tas !" "1": "@c{smile}Ah, je te cherchais ! Je savais que tétais pressée de partir, mais je mattendais quand même à un au revoir…\n$@c{smile_eclosed}Tas finalement décidé de réaliser ton rêve ?\nJai peine à y croire.\n$@c{serious_smile_fists}Vu que tes là, ça te dis un petit combat ?\nJe voudrais quand même massurer que tes prête.\n$@c{serious_mopen_fists}Surtout ne te retiens pas et donne-moi tout ce que tas !"
}, },
"victory": { "victory": {
"1": "@c{shock}Wah… Tu mas vraiment lavé.\nTes vraiment une débutante ?\n$@c{smile}Tas peut-être eu de la chance, mais…\nPeut-être que tarriveras jusquau bout du chemin.\n$Dailleurs, le prof ma demandé de te filer ces objets.\nIls ont lair sympas.\n$@c{serious_smile_fists}Bonne chance à toi !" "1": "@c{shock}Wah… Tu mas vraiment lavé.\nTes vraiment une débutante ?\n$@c{smile}Tas peut-être eu de la chance, mais…\nPeut-être que tarriveras jusquau bout du chemin.\n$Dailleurs, le prof ma demandé de te filer ces objets.\nIls ont lair sympas.\n$@c{serious_smile_fists}Bonne chance à toi !"
} }
}, },
"rival_female": { "rival_female": {
"encounter": { "encounter": {
"1": "@c{smile_wave}Ah, te voilà ! Je tai cherché partout !\n@c{angry_mopen}On oublie de dire au revoir à sa meilleure amie ?\n$@c{smile_ehalf}Tas décidé de réaliser ton rêve, hein ?\nCe jour est donc vraiment arrivé…\n$@c{smile}Je veux bien te pardonner de mavoir oubliée,\nà une condition. @c{smile_wave_wink}Que tu maffronte !\n$@c{angry_mopen}Donne tout ! Ce serait dommage que ton aventure finisse avant davoir commencé, hein ?" "1": "@c{smile_wave}Ah, te voilà ! Je tai cherché partout !\n@c{angry_mopen}On oublie de dire au revoir à sa meilleure amie ?\n$@c{smile_ehalf}Tas décidé de réaliser ton rêve, hein ?\nCe jour est donc vraiment arrivé…\n$@c{smile}Je veux bien te pardonner de mavoir oubliée,\nà une condition. @c{smile_wave_wink}Que tu maffronte !\n$@c{angry_mopen}Donne tout ! Ce serait dommage que ton aventure finisse avant davoir commencé, hein ?"
}, },
"victory": { "victory": {
"1": "@c{shock}Tu viens de commencer et tes déjà si fort ?!@d{96}\n@c{angry}Tas triché non ? Avoue !\n$@c{smile_wave_wink}Jdéconne !@d{64} @c{smile_eclosed}Jai perdu dans les règles…\nJai le sentiment que tu vas très bien ten sortir.\n$@c{smile}Dailleurs, le prof veut que je te donne ces quelques objets. Ils te seront utiles, pour sûr !\n$@c{smile_wave}Fais de ton mieux, comme toujours !\nJe crois fort en toi !" "1": "@c{shock}Tu viens de commencer et tes déjà si fort ?!@d{96}\n@c{angry}Tas triché non ? Avoue !\n$@c{smile_wave_wink}Jdéconne !@d{64} @c{smile_eclosed}Jai perdu dans les règles…\nJai le sentiment que tu vas très bien ten sortir.\n$@c{smile}Dailleurs, le prof veut que je te donne ces quelques objets. Ils te seront utiles, pour sûr !\n$@c{smile_wave}Fais de ton mieux, comme toujours !\nJe crois fort en toi !"
} }
}, },
"rival_2": { "rival_2": {
"encounter": { "encounter": {
"1": "@c{smile}Hé, toi aussi tes là ?\n@c{smile_eclosed}Toujours invaincue, hein… ?\n$@c{serious_mopen_fists}Je sais que jai lair de tavoir suivie ici, mais cest pas complètement vrai.\n$@c{serious_smile_fists}Pour être honnête, ça me démangeait davoir une revanche depuis que tu mas battu.\n$Je me suis beaucoup entrainé, alors sois sure que je vais pas retenir mes coups cette fois.\n$@c{serious_mopen_fists}Et comme la dernière fois, ne te retiens pas !\nCest parti !" "1": "@c{smile}Hé, toi aussi tes là ?\n@c{smile_eclosed}Toujours invaincue, hein… ?\n$@c{serious_mopen_fists}Je sais que jai lair de tavoir suivie ici, mais cest pas complètement vrai.\n$@c{serious_smile_fists}Pour être honnête, ça me démangeait davoir une revanche depuis que tu mas battu.\n$Je me suis beaucoup entrainé, alors sois sure que je vais pas retenir mes coups cette fois.\n$@c{serious_mopen_fists}Et comme la dernière fois, ne te retiens pas !\nCest parti !"
}, },
"victory": { "victory": {
"1": "@c{neutral_eclosed}Oh. Je crois que jai trop pris la confiance.\n$@c{smile}Pas grave, cest OK. Je me doutais que ça arriverait.\n@c{serious_mopen_fists}Je vais juste devoir encore plus mentrainer !\n\n$@c{smile}Ah, et pas que taies réellement besoin daide, mais jai ça en trop sur moi qui pourrait tintéresser.\n\n$@c{serious_smile_fists}Mais nespère plus en avoir dautres !\nJe peux pas passer mon temps à aider mon adversaire.\n$@c{smile}Bref, prends soin de toi !" "1": "@c{neutral_eclosed}Oh. Je crois que jai trop pris la confiance.\n$@c{smile}Pas grave, cest OK. Je me doutais que ça arriverait.\n@c{serious_mopen_fists}Je vais juste devoir encore plus mentrainer !\n\n$@c{smile}Ah, et pas que taies réellement besoin daide, mais jai ça en trop sur moi qui pourrait tintéresser.\n\n$@c{serious_smile_fists}Mais nespère plus en avoir dautres !\nJe peux pas passer mon temps à aider mon adversaire.\n$@c{smile}Bref, prends soin de toi !"
} }
}, },
"rival_2_female": { "rival_2_female": {
"encounter": { "encounter": {
"1": "@c{smile_wave}Hé, sympa de te croiser ici. Tas toujours lair invaincu. @c{angry_mopen}Eh… Pas mal !\n$@c{angry_mopen}Je sais à quoi tu penses et non, je tespionne pas.\n@c{smile_eclosed}Cest juste que jétais aussi dans le coin.\n$@c{smile_ehalf}Heureuse pour toi, mais je veux juste te rappeler que cest pas grave de perdre parfois.\n$@c{smile}On apprend de nos erreurs, souvent plus que si on ne connaissait que le succès.\n$@c{angry_mopen}Dans tous les cas je me suis bien entrainée pour cette revanche, tas intérêt à tout donner !" "1": "@c{smile_wave}Hé, sympa de te croiser ici. Tas toujours lair invaincu. @c{angry_mopen}Eh… Pas mal !\n$@c{angry_mopen}Je sais à quoi tu penses et non, je tespionne pas.\n@c{smile_eclosed}Cest juste que jétais aussi dans le coin.\n$@c{smile_ehalf}Heureuse pour toi, mais je veux juste te rappeler que cest pas grave de perdre parfois.\n$@c{smile}On apprend de nos erreurs, souvent plus que si on ne connaissait que le succès.\n$@c{angry_mopen}Dans tous les cas je me suis bien entrainée pour cette revanche, tas intérêt à tout donner !"
}, },
"victory": { "victory": {
"1": "@c{neutral}Je… Jétais pas encore supposée perdre…\n$@c{smile}Bon. Ça veut juste dire que je vais devoir encore plus mentrainer !\n$@c{smile_wave}Jai aussi ça en rab pour toi !\n@c{smile_wave_wink}Inutile de me remercier ~.\n$@c{angry_mopen}Cétaient les derniers, terminé les cadeaux après ceux-là !\n$@c{smile_wave}Allez, tiens le coup !" "1": "@c{neutral}Je… Jétais pas encore supposée perdre…\n$@c{smile}Bon. Ça veut juste dire que je vais devoir encore plus mentrainer !\n$@c{smile_wave}Jai aussi ça en rab pour toi !\n@c{smile_wave_wink}Inutile de me remercier ~.\n$@c{angry_mopen}Cétaient les derniers, terminé les cadeaux après ceux-là !\n$@c{smile_wave}Allez, tiens le coup !"
}, },
"defeat": { "defeat": {
"1": "Je suppose que cest parfois normal de perdre…" "1": "Je suppose que cest parfois normal de perdre…"
@ -630,18 +630,18 @@
}, },
"rival_3": { "rival_3": {
"encounter": { "encounter": {
"1": "@c{smile}Hé, mais qui voilà ! Ça fait un bail.\n@c{neutral}Tes… toujours invaincue ? Incroyable.\n$@c{neutral_eclosed}Tout est devenu un peu… étrange.\nCest plus pareil sans toi au village.\n$@c{serious}Je sais que cest égoïste, mais jai besoin dexpier ça.\n@c{neutral_eclosed}Je crois que tout ça te dépasse.\n$@c{serious}Ne jamais perdre, cest juste irréaliste.\nGrandir, cest parfois aussi savoir perdre.\n$@c{neutral_eclosed}Tas un beau parcours, mais il y a encore tellement à venir et ça va pas sarranger. @c{neutral}Tes prête pour ça ?\n$@c{serious_mopen_fists}Si tu les, alors prouve-le." "1": "@c{smile}Hé, mais qui voilà ! Ça fait un bail.\n@c{neutral}Tes… toujours invaincue ? Incroyable.\n$@c{neutral_eclosed}Tout est devenu un peu… étrange.\nCest plus pareil sans toi au village.\n$@c{serious}Je sais que cest égoïste, mais jai besoin dexpier ça.\n@c{neutral_eclosed}Je crois que tout ça te dépasse.\n$@c{serious}Ne jamais perdre, cest juste irréaliste.\nGrandir, cest parfois aussi savoir perdre.\n$@c{neutral_eclosed}Tas un beau parcours, mais il y a encore tellement à venir et ça va pas sarranger. @c{neutral}Tes prête pour ça ?\n$@c{serious_mopen_fists}Si tu les, alors prouve-le."
}, },
"victory": { "victory": {
"1": "@c{angry_mhalf}Cest lunaire… Jai presque fait que mentrainer…\nAlors pourquoi il y a encore un tel écart entre nous ?" "1": "@c{angry_mhalf}Cest lunaire… Jai presque fait que mentrainer…\nAlors pourquoi il y a encore un tel écart entre nous ?"
} }
}, },
"rival_3_female": { "rival_3_female": {
"encounter": { "encounter": {
"1": "@c{smile_wave}Ça fait une éternité ! Toujours debout hein ?\n@c{angry}Tu commences à me pousser à bout là. @c{smile_wave_wink}Tinquiètes jdéconne !\n$@c{smile_ehalf}Mais en vrai, ta maison te manque pas ? Ou… Moi ?\nJ… Je veux dire… Tu me manques vraiment beaucoup.\n$@c{smile_eclosed}Je te soutiendrai toujours dans tes ambitions, mais la vérité est que tu finiras par perdre un jour ou lautre.\n$@c{smile}Quand ça arrivera, je serai là pour toi, comme toujours.\n@c{angry_mopen}Maintenant, montre-moi à quel point tes devenu fort !" "1": "@c{smile_wave}Ça fait une éternité ! Toujours debout hein ?\n@c{angry}Tu commences à me pousser à bout là. @c{smile_wave_wink}Tinquiètes jdéconne !\n$@c{smile_ehalf}Mais en vrai, ta maison te manque pas ? Ou… Moi ?\nJ… Je veux dire… Tu me manques vraiment beaucoup.\n$@c{smile_eclosed}Je te soutiendrai toujours dans tes ambitions, mais la vérité est que tu finiras par perdre un jour ou lautre.\n$@c{smile}Quand ça arrivera, je serai là pour toi, comme toujours.\n@c{angry_mopen}Maintenant, montre-moi à quel point tes devenu fort !"
}, },
"victory": { "victory": {
"1": "@c{shock}Après tout ça… Ça te suffit toujours pas… ?\nTu reviendras jamais à ce rythme…" "1": "@c{shock}Après tout ça… Ça te suffit toujours pas… ?\nTu reviendras jamais à ce rythme…"
}, },
"defeat": { "defeat": {
"1": "Tas fait de ton mieux.\nAllez, rentrons à la maison." "1": "Tas fait de ton mieux.\nAllez, rentrons à la maison."
@ -652,15 +652,15 @@
"1": "@c{neutral}Hé.\n$Je vais pas y aller par quatre chemins avec toi.\n@c{neutral_eclosed}Je suis là pour gagner. Simple, basique.\n$@c{serious_mhalf_fists}Jai appris à maximiser tout mon potentiel en mentrainant darrachepied.\n$@c{smile}Cest fou tout le temps que tu peux te dégager si tu dors pas en sacrifiant ta vie sociale.\n$@c{serious_mopen_fists}Plus rien na dimportance désormais, pas tant que jaurai pas gagné.\n$@c{neutral_eclosed}Jai atteint un stade où je ne peux plus perdre.\n@c{smile_eclosed}Je présume que ta philosophie était pas si fausse finalement.\n$@c{angry_mhalf}La défaite, cest pour les faibles, et je ne suis plus un faible.\n$@c{serious_mopen_fists}Tiens-toi prête." "1": "@c{neutral}Hé.\n$Je vais pas y aller par quatre chemins avec toi.\n@c{neutral_eclosed}Je suis là pour gagner. Simple, basique.\n$@c{serious_mhalf_fists}Jai appris à maximiser tout mon potentiel en mentrainant darrachepied.\n$@c{smile}Cest fou tout le temps que tu peux te dégager si tu dors pas en sacrifiant ta vie sociale.\n$@c{serious_mopen_fists}Plus rien na dimportance désormais, pas tant que jaurai pas gagné.\n$@c{neutral_eclosed}Jai atteint un stade où je ne peux plus perdre.\n@c{smile_eclosed}Je présume que ta philosophie était pas si fausse finalement.\n$@c{angry_mhalf}La défaite, cest pour les faibles, et je ne suis plus un faible.\n$@c{serious_mopen_fists}Tiens-toi prête."
}, },
"victory": { "victory": {
"1": "@c{neutral}Que…@d{64} Qui es-tu ?" "1": "@c{neutral}Que…@d{64} Qui es-tu ?"
} }
}, },
"rival_4_female": { "rival_4_female": {
"encounter": { "encounter": {
"1": "@c{neutral}Cest moi ! Tu mas pas encore oubliée… nest-ce pas ?\n$@c{smile}Tu devrais être fier dêtre arrivé aussi loin. GG !\nMais cest certainement pas la fin de ton aventure.\n$@c{smile_eclosed}Tas éveillé en moi quelque chose que jignorais.\nTout mon temps passe dans lentrainement.\n$@c{smile_ehalf}Je dors et je mange à peine, je mentraine juste tous les jours, et deviens de plus en plus forte.\n$@c{neutral}En vrai, Je… Jai de la peine à me reconnaitre.\n$Mais maintenant, je suis au top de mes capacités.\nJe doute que tu sois de nouveau capable de me battre.\n$Et tu sais quoi ? Tout ça, cest de ta faute.\n@c{smile_ehalf}Et jignore si je dois te remercier ou te haïr.\n$@c{angry_mopen}Tiens-toi prêt." "1": "@c{neutral}Cest moi ! Tu mas pas encore oubliée… nest-ce pas ?\n$@c{smile}Tu devrais être fier dêtre arrivé aussi loin. GG !\nMais cest certainement pas la fin de ton aventure.\n$@c{smile_eclosed}Tas éveillé en moi quelque chose que jignorais.\nTout mon temps passe dans lentrainement.\n$@c{smile_ehalf}Je dors et je mange à peine, je mentraine juste tous les jours, et deviens de plus en plus forte.\n$@c{neutral}En vrai, Je… Jai de la peine à me reconnaitre.\n$Mais maintenant, je suis au top de mes capacités.\nJe doute que tu sois de nouveau capable de me battre.\n$Et tu sais quoi ? Tout ça, cest de ta faute.\n@c{smile_ehalf}Et jignore si je dois te remercier ou te haïr.\n$@c{angry_mopen}Tiens-toi prêt."
}, },
"victory": { "victory": {
"1": "@c{neutral}Que…@d{64} Qui es-tu ?" "1": "@c{neutral}Que…@d{64} Qui es-tu ?"
}, },
"defeat": { "defeat": {
"1": "$@c{smile}Tu devrais être fier dêtre arrivé jusque là." "1": "$@c{smile}Tu devrais être fier dêtre arrivé jusque là."
@ -687,7 +687,7 @@
}, },
"rival_6": { "rival_6": {
"encounter": { "encounter": {
"1": "@c{smile_eclosed}Nous y revoilà.\n$@c{neutral}Jai eu du temps pour réfléchir à tout ça.\nIl y a une raison à pourquoi tout semble étrange.\n$@c{neutral_eclosed}Ton rêve, ma volonté de te battre…\nFont partie de quelque chose de plus grand.\n$@c{serious}Cest même pas à propos de moi, ni de toi… Mais du monde, @c{serious_mhalf_fists}et te repousser dans tes limites est ma mission.\n$@c{neutral_eclosed}Jignore si je serai capable de laccomplir, mais je ferai tout ce qui est en mon pouvoir.\n$@c{neutral}Cet endroit est terrifiant… Et pourtant il ma lair familier, comme si jy avais déjà mis les pieds.\n$@c{serious_mhalf_fists}Tu ressens la même chose, pas vrai ?\n$@c{serious}… et cest comme si quelque chose ici me parlait.\n$Comme si cétait tout ce que ce monde avait toujours connu.\n$Ces précieux moments ensemble semblent si proches ne sont rien de plus quun lointain souvenir.\n$@c{neutral_eclosed}Dailleurs, qui peut dire aujourdhui quils ont pu être réels ?\n$@c{serious_mopen_fists}Il faut que tu persévères. Si tu tarrêtes, ça naura jamais de fin et tes la seule à en être capable.\n$@c{serious_smile_fists}Difficile de comprendre le sens de tout ça, je sais juste que cest la réalité.\n$@c{serious_mopen_fists}Si tu ne parviens pas à me battre ici et maintenant, tu nas aucune chance." "1": "@c{smile_eclosed}Nous y revoilà.\n$@c{neutral}Jai eu du temps pour réfléchir à tout ça.\nIl y a une raison à pourquoi tout semble étrange.\n$@c{neutral_eclosed}Ton rêve, ma volonté de te battre…\nFont partie de quelque chose de plus grand.\n$@c{serious}Cest même pas à propos de moi, ni de toi… Mais du monde, @c{serious_mhalf_fists}et te repousser dans tes limites est ma mission.\n$@c{neutral_eclosed}Jignore si je serai capable de laccomplir, mais je ferai tout ce qui est en mon pouvoir.\n$@c{neutral}Cet endroit est terrifiant… Et pourtant il ma lair familier, comme si jy avais déjà mis les pieds.\n$@c{serious_mhalf_fists}Tu ressens la même chose, pas vrai ?\n$@c{serious}… et cest comme si quelque chose ici me parlait.\n$Comme si cétait tout ce que ce monde avait toujours connu.\n$Ces précieux moments ensemble semblent si proches ne sont rien de plus quun lointain souvenir.\n$@c{neutral_eclosed}Dailleurs, qui peut dire aujourdhui quils ont pu être réels ?\n$@c{serious_mopen_fists}Il faut que tu persévères. Si tu tarrêtes, ça naura jamais de fin et tes la seule à en être capable.\n$@c{serious_smile_fists}Difficile de comprendre le sens de tout ça, je sais juste que cest la réalité.\n$@c{serious_mopen_fists}Si tu ne parviens pas à me battre ici et maintenant, tu nas aucune chance."
}, },
"victory": { "victory": {
"1": "@c{smile_eclosed}Jai fait ce que javais à faire.\n$Promets-moi juste une chose.\n@c{smile}Après avoir réparé ce monde… Rentre à la maison." "1": "@c{smile_eclosed}Jai fait ce que javais à faire.\n$Promets-moi juste une chose.\n@c{smile}Après avoir réparé ce monde… Rentre à la maison."
@ -695,7 +695,7 @@
}, },
"rival_6_female": { "rival_6_female": {
"encounter": { "encounter": {
"1": "@c{smile_ehalf}Cest donc encore entre toi et moi.\n$@c{smile_eclosed}Tu sais, jai beau retouner ça dans tous les sens…\n$@c{smile_ehalf}Quelque chose peut expliquer tout ça, pourquoi tout semble si étrange…\n$@c{smile}Tas tes rêves, jai mes ambitions…\n$Jai juste le sentiment quil y a un grand dessein derrière tout ça, derrière ce quon fait toi et moi.\n$@c{smile_eclosed}Je crois que mon but est de… repousser tes limites.\n$@c{smile_ehalf}Je suis pas certaine de bien être douée à cet exercice, mais je fais de mon mieux.\n$Cet endroit épouvantable cache quelque chose détrange… Tout semble si limpide…\n$Comme… si cétait tout ce que ce monde avait toujours connu.\n$@c{smile_eclosed}Jai le sentiment que nos précieux moments ensemble sont devenus si flous.\n$@c{smile_ehalf}Ont-ils au moins été réels ? Tout semble si loin maintenant…\n$@c{angry_mopen}Il faut que tu persévères. Si tu tarrêtes, ça naura jamais de fin et tes le seul à en être capable.\n$@c{smile_ehalf}Je… jignore le sens de tout ça… Mais je sais que cest la réalité.\n$@c{neutral}Si tu ne parviens pas à me battre ici et maintenant, tu nas aucune chance." "1": "@c{smile_ehalf}Cest donc encore entre toi et moi.\n$@c{smile_eclosed}Tu sais, jai beau retouner ça dans tous les sens…\n$@c{smile_ehalf}Quelque chose peut expliquer tout ça, pourquoi tout semble si étrange…\n$@c{smile}Tas tes rêves, jai mes ambitions…\n$Jai juste le sentiment quil y a un grand dessein derrière tout ça, derrière ce quon fait toi et moi.\n$@c{smile_eclosed}Je crois que mon but est de… repousser tes limites.\n$@c{smile_ehalf}Je suis pas certaine de bien être douée à cet exercice, mais je fais de mon mieux.\n$Cet endroit épouvantable cache quelque chose détrange… Tout semble si limpide…\n$Comme… si cétait tout ce que ce monde avait toujours connu.\n$@c{smile_eclosed}Jai le sentiment que nos précieux moments ensemble sont devenus si flous.\n$@c{smile_ehalf}Ont-ils au moins été réels ? Tout semble si loin maintenant…\n$@c{angry_mopen}Il faut que tu persévères. Si tu tarrêtes, ça naura jamais de fin et tes le seul à en être capable.\n$@c{smile_ehalf}Je… jignore le sens de tout ça… Mais je sais que cest la réalité.\n$@c{neutral}Si tu ne parviens pas à me battre ici et maintenant, tu nas aucune chance."
}, },
"victory": { "victory": {
"1": "@c{smile_ehalf}Je… Je crois que jai rempli ma mission…\n$@c{smile_eclosed}Promets-moi… Après avoir réparé ce monde… Reviens à la maison sain et sauf.\n$@c{smile_ehalf}… Merci." "1": "@c{smile_ehalf}Je… Je crois que jai rempli ma mission…\n$@c{smile_eclosed}Promets-moi… Après avoir réparé ce monde… Reviens à la maison sain et sauf.\n$@c{smile_ehalf}… Merci."

View File

@ -4,7 +4,7 @@
"ultraTier": "Épique", "ultraTier": "Épique",
"masterTier": "Légendaire", "masterTier": "Légendaire",
"defaultTier": "Commun", "defaultTier": "Commun",
"hatchWavesMessageSoon": "Il fait du bruit. Il va éclore !", "hatchWavesMessageSoon": "Il fait du bruit.\nIl va éclore !",
"hatchWavesMessageClose": "Il bouge de temps en temps. Il devrait bientôt éclore.", "hatchWavesMessageClose": "Il bouge de temps en temps. Il devrait bientôt éclore.",
"hatchWavesMessageNotClose": "Quest-ce qui va en sortir ? Ça va mettre du temps.", "hatchWavesMessageNotClose": "Quest-ce qui va en sortir ? Ça va mettre du temps.",
"hatchWavesMessageLongTime": "Cet Œuf va surement mettre du temps à éclore.", "hatchWavesMessageLongTime": "Cet Œuf va surement mettre du temps à éclore.",
@ -16,7 +16,7 @@
"tooManyEggs": "Vous avez trop dŒufs !", "tooManyEggs": "Vous avez trop dŒufs !",
"pull": "Tirage", "pull": "Tirage",
"pulls": "Tirages", "pulls": "Tirages",
"sameSpeciesEgg": "{{species}} sortira de cet Œuf !", "sameSpeciesEgg": "Un {{species}} sortira de cet Œuf !",
"hatchFromTheEgg": "{{pokemonName}} sort de lŒuf !", "hatchFromTheEgg": "{{pokemonName}} sort de lŒuf !",
"eggMoveUnlock": "Capacité Œuf débloquée :\n{{moveName}}", "eggMoveUnlock": "Capacité Œuf débloquée :\n{{moveName}}",
"rareEggMoveUnlock": "Capacité Œuf Rare débloquée :\n{{moveName}}", "rareEggMoveUnlock": "Capacité Œuf Rare débloquée :\n{{moveName}}",

View File

@ -6,7 +6,7 @@
"newGame": "Nouvelle partie", "newGame": "Nouvelle partie",
"settings": "Paramètres", "settings": "Paramètres",
"selectGameMode": "Sélectionnez un mode de jeu.", "selectGameMode": "Sélectionnez un mode de jeu.",
"logInOrCreateAccount": "Connectez-vous ou créez un compte pour commencer. Aucun e-mail requis !", "logInOrCreateAccount": "Connectez-vous ou créez un compte pour commencer.\nAucun e-mail requis !",
"username": "Nom dutilisateur", "username": "Nom dutilisateur",
"password": "Mot de passe", "password": "Mot de passe",
"login": "Connexion", "login": "Connexion",
@ -19,29 +19,29 @@
"invalidRegisterPassword": "Le mot de passe doit contenir 6 caractères ou plus", "invalidRegisterPassword": "Le mot de passe doit contenir 6 caractères ou plus",
"usernameAlreadyUsed": "Le nom dutilisateur est déjà utilisé", "usernameAlreadyUsed": "Le nom dutilisateur est déjà utilisé",
"accountNonExistent": "Le nom dutilisateur nexiste pas", "accountNonExistent": "Le nom dutilisateur nexiste pas",
"unmatchingPassword": "Le mot de passe nest pas correct", "unmatchingPassword": "Le mot de passe est incorrect",
"passwordNotMatchingConfirmPassword": "Les mots de passe ne correspondent pas", "passwordNotMatchingConfirmPassword": "Les mots de passe ne correspondent pas",
"confirmPassword": "Confirmer le MDP", "confirmPassword": "Confirmer le MDP",
"registrationAgeWarning": "Vous confirmez en vous inscrivant que vous avez 13 ans ou plus.", "registrationAgeWarning": "En vous inscrivant, vous certifiez que vous avez 13 ans ou plus.",
"backToLogin": "Retour", "backToLogin": "Retour",
"failedToLoadSaveData": "Échec du chargement des données. Veuillez recharger\nla page. Si cela persiste, contactez ladministrateur.", "failedToLoadSaveData": "Échec du chargement des données. Veuillez recharger\nla page. Si cela persiste, contactez ladministrateur.",
"sessionSuccess": "Session chargée avec succès.", "sessionSuccess": "Session chargée avec succès.",
"failedToLoadSession": "Vos données de session nont pas pu être chargées.\nElles pourraient être corrompues.", "failedToLoadSession": "Vos données de session nont pas pu être chargées.\nElles pourraient être corrompues.",
"boyOrGirl": "Es-tu un garçon ou une fille ?", "boyOrGirl": "Es-tu un garçon ou une fille ?",
"evolving": "Quoi ?\n{{pokemonName}} évolue !", "evolving": "Quoi ?\n{{pokemonName}} évolue !",
"stoppedEvolving": "Hein ?\n{{pokemonName}} névolue plus !", "stoppedEvolving": "Hein ?\n{{pokemonName}} névolue plus !",
"pauseEvolutionsQuestion": "Mettre en pause les évolutions pour {{pokemonName}} ?\nElles peuvent être réactivées depuis lécran déquipe.", "pauseEvolutionsQuestion": "Interrompre les évolutions pour {{pokemonName}} ?\nElles peuvent être réactivées depuis lécran déquipe.",
"evolutionsPaused": "Les évolutions ont été mises en pause pour {{pokemonName}}.", "evolutionsPaused": "Les évolutions de {{pokemonName}}\nsont interrompues.",
"evolutionDone": "Félicitations !\n{{pokemonName}} a évolué en {{evolvedPokemonName}} !", "evolutionDone": "Félicitations !\n{{pokemonName}} a évolué en {{evolvedPokemonName}} !",
"dailyRankings": "Classement du Jour", "dailyRankings": "Classement du jour",
"weeklyRankings": "Classement de la Semaine", "weeklyRankings": "Classement de la semaine",
"noRankings": "Pas de Classement", "noRankings": "Pas de classement",
"positionIcon": "#", "positionIcon": "#",
"usernameScoreboard": "Utilisateur", "usernameScoreboard": "Utilisateur",
"score": "Score", "score": "Score",
"wave": "Vague", "wave": "Vague",
"loading": "Chargement…", "loading": "Chargement…",
"loadingAsset": "Chargement de la ressource : {{assetName}}", "loadingAsset": "Chargement des ressources : {{assetName}}",
"playersOnline": "Joueurs connectés", "playersOnline": "Joueurs connectés",
"yes": "Oui", "yes": "Oui",
"no": "Non", "no": "Non",
@ -51,5 +51,7 @@
"renamePokemon": "Renommer le Pokémon", "renamePokemon": "Renommer le Pokémon",
"rename": "Renommer", "rename": "Renommer",
"nickname": "Surnom", "nickname": "Surnom",
"errorServerDown": "Oupsi ! Un problème de connexion au serveur est survenu.\n\nVous pouvez garder cette fenêtre ouverte,\nle jeu se reconnectera automatiquement." "errorServerDown": "Oupsi ! Un problème de connexion au serveur est survenu.\n\nVous pouvez garder cette fenêtre ouverte,\nle jeu se reconnectera automatiquement.",
"noSaves": "Vous navez aucune sauvegarde enregistrée !",
"tooManySaves": "Vous avez trop de sauvegardes enregistrées !"
} }

View File

@ -2,7 +2,7 @@
"ModifierType": { "ModifierType": {
"AddPokeballModifierType": { "AddPokeballModifierType": {
"name": "{{pokeballName}} x{{modifierCount}}", "name": "{{pokeballName}} x{{modifierCount}}",
"description": "Recevez {{modifierCount}} {{pokeballName}}·s. (Inventaire : {{pokeballAmount}})\nTaux de capture : {{catchRate}}" "description": "Recevez {{modifierCount}} {{pokeballName}}·s. (Inventaire : {{pokeballAmount}})\nTaux de capture : {{catchRate}}"
}, },
"AddVoucherModifierType": { "AddVoucherModifierType": {
"name": "{{voucherTypeName}} x{{modifierCount}}", "name": "{{voucherTypeName}} x{{modifierCount}}",
@ -10,8 +10,8 @@
}, },
"PokemonHeldItemModifierType": { "PokemonHeldItemModifierType": {
"extra": { "extra": {
"inoperable": "{{pokemonName}} ne peut pas\nporter cet objet !", "inoperable": "{{pokemonName}} ne peut pas\nporter cet objet !",
"tooMany": "{{pokemonName}} porte trop\ndexemplaires de cet objet !" "tooMany": "{{pokemonName}} porte trop\ndexemplaires de cet objet !"
} }
}, },
"PokemonHpRestoreModifierType": { "PokemonHpRestoreModifierType": {
@ -47,10 +47,14 @@
"description": "Donne la nature {{natureName}} à un Pokémon et la débloque pour le starter lui étant lié." "description": "Donne la nature {{natureName}} à un Pokémon et la débloque pour le starter lui étant lié."
}, },
"DoubleBattleChanceBoosterModifierType": { "DoubleBattleChanceBoosterModifierType": {
"description": "Double les chances de tomber sur un combat double pendant {{battleCount}} combats." "description": "Quadruple les chances de tomber sur un combat double pendant {{battleCount}} combats."
}, },
"TempStatStageBoosterModifierType": { "TempStatStageBoosterModifierType": {
"description": "Augmente dun cran {{stat}} pour toute léquipe pendant 5 combats." "description": "Augmente {{amount}} {{stat}} de toute léquipe pendant 5 combats.",
"extra": {
"stage": "dun cran",
"percentage": "de 30%"
}
}, },
"AttackTypeBoosterModifierType": { "AttackTypeBoosterModifierType": {
"description": "Augmente de 20% la puissance des capacités de type {{moveType}} dun Pokémon." "description": "Augmente de 20% la puissance des capacités de type {{moveType}} dun Pokémon."
@ -85,7 +89,7 @@
"description": "Augmente de {{boostPercent}}% le gain de Points dExp du porteur." "description": "Augmente de {{boostPercent}}% le gain de Points dExp du porteur."
}, },
"PokemonFriendshipBoosterModifierType": { "PokemonFriendshipBoosterModifierType": {
"description": "Augmente le gain damitié de 50% par victoire." "description": "Augmente le gain de bonheur de 50% par victoire."
}, },
"PokemonMoveAccuracyBoosterModifierType": { "PokemonMoveAccuracyBoosterModifierType": {
"description": "Augmente de {{accuracyAmount}} la précision des capacités (maximum 100)." "description": "Augmente de {{accuracyAmount}} la précision des capacités (maximum 100)."
@ -102,17 +106,17 @@
"description": "Apprend la capacité {{moveName}} à un Pokémon.\n(Maintenez C ou Maj pour plus dinfos)" "description": "Apprend la capacité {{moveName}} à un Pokémon.\n(Maintenez C ou Maj pour plus dinfos)"
}, },
"EvolutionItemModifierType": { "EvolutionItemModifierType": {
"description": "Permet à certains Pokémon dévoluer." "description": "Permet à certains Pokémon dévoluer à son contact."
}, },
"FormChangeItemModifierType": { "FormChangeItemModifierType": {
"description": "Permet à certains Pokémon de changer de forme." "description": "Permet à certains Pokémon de changer de forme à son contact."
}, },
"FusePokemonModifierType": { "FusePokemonModifierType": {
"description": "Fusionne deux Pokémon (transfère le talent, sépare les stats de base et les types, partage les capacités)." "description": "Fusionne deux Pokémon (transfère le talent, sépare les stats de base et les types, partage les capacités)."
}, },
"TerastallizeModifierType": { "TerastallizeModifierType": {
"name": "Téra-Éclat {{teraType}}", "name": "Téra-Éclat {{teraType}}",
"description": "{{teraType}} Téracristallise son porteur pendant 10 combats." "description": "Téracristallise son porteur en type {{teraType}} pendant 10 combats."
}, },
"ContactHeldItemTransferChanceModifierType": { "ContactHeldItemTransferChanceModifierType": {
"description": "{{chancePercent}}% de chances de voler un objet de ladversaire en lattaquant." "description": "{{chancePercent}}% de chances de voler un objet de ladversaire en lattaquant."
@ -247,7 +251,7 @@
}, },
"SpeciesBoosterItem": { "SpeciesBoosterItem": {
"LIGHT_BALL": { "name": "Balle Lumière", "description": "À faire tenir à Pikachu. Un orbe énigmatique qui double son Attaque et son Atq. Spé. ." }, "LIGHT_BALL": { "name": "Balle Lumière", "description": "À faire tenir à Pikachu. Un orbe énigmatique qui double son Attaque et son Atq. Spé. ." },
"THICK_CLUB": { "name": "Masse Os", "description": "À faire tenir à Osselait ou Ossatueur. Un os dur qui double leur Attaque." }, "THICK_CLUB": { "name": "Masse Os", "description": "À faire tenir à Osselait ou à Ossatueur, formes dAlola incluses. Un os dur qui double leur Attaque." },
"METAL_POWDER": { "name": "Poudre Métal", "description": "À faire tenir à Métamorph. Cette poudre étrange, très fine mais résistante, double sa Défense." }, "METAL_POWDER": { "name": "Poudre Métal", "description": "À faire tenir à Métamorph. Cette poudre étrange, très fine mais résistante, double sa Défense." },
"QUICK_POWDER": { "name": "Poudre Vite", "description": "À faire tenir à Métamorph. Cette poudre étrange, très fine mais résistante, double sa Vitesse." } "QUICK_POWDER": { "name": "Poudre Vite", "description": "À faire tenir à Métamorph. Cette poudre étrange, très fine mais résistante, double sa Vitesse." }
}, },

View File

@ -3,7 +3,7 @@
"turnHealApply": "Les PV de {{pokemonNameWithAffix}}\nsont un peu restaurés par les {{typeName}} !", "turnHealApply": "Les PV de {{pokemonNameWithAffix}}\nsont un peu restaurés par les {{typeName}} !",
"hitHealApply": "Les PV de {{pokemonNameWithAffix}}\nsont un peu restaurés par le {{typeName}} !", "hitHealApply": "Les PV de {{pokemonNameWithAffix}}\nsont un peu restaurés par le {{typeName}} !",
"pokemonInstantReviveApply": "{{pokemonNameWithAffix}} a repris connaissance\navec sa {{typeName}} et est prêt à se battre de nouveau !", "pokemonInstantReviveApply": "{{pokemonNameWithAffix}} a repris connaissance\navec sa {{typeName}} et est prêt à se battre de nouveau !",
"resetNegativeStatStageApply": "Les stats baissées de {{pokemonNameWithAffix}}\nsont restaurées par l{{typeName}} !", "resetNegativeStatStageApply": "Les stats baissées de {{pokemonNameWithAffix}}\nsont restaurées par l{{typeName}} !",
"moneyInterestApply": "La {{typeName}} vous rapporte\n{{moneyAmount}}  dintérêts !", "moneyInterestApply": "La {{typeName}} vous rapporte\n{{moneyAmount}}  dintérêts !",
"turnHeldItemTransferApply": "{{itemName}} de {{pokemonNameWithAffix}} est absorbé·e\npar le {{typeName}} de {{pokemonName}} !", "turnHeldItemTransferApply": "{{itemName}} de {{pokemonNameWithAffix}} est absorbé·e\npar le {{typeName}} de {{pokemonName}} !",
"contactHeldItemTransferApply": "{{itemName}} de {{pokemonNameWithAffix}} est volé·e\npar l{{typeName}} de {{pokemonName}} !", "contactHeldItemTransferApply": "{{itemName}} de {{pokemonNameWithAffix}} est volé·e\npar l{{typeName}} de {{pokemonName}} !",

View File

@ -3,10 +3,10 @@
"cutHpPowerUpMove": "{{pokemonName}} sacrifie des PV\net augmente la puissance ses capacités !", "cutHpPowerUpMove": "{{pokemonName}} sacrifie des PV\net augmente la puissance ses capacités !",
"absorbedElectricity": "{{pokemonName}} absorbe de lélectricité !", "absorbedElectricity": "{{pokemonName}} absorbe de lélectricité !",
"switchedStatChanges": "{{pokemonName}} permute\nles changements de stats avec ceux de sa cible !", "switchedStatChanges": "{{pokemonName}} permute\nles changements de stats avec ceux de sa cible !",
"switchedTwoStatChanges": "{{pokemonName}} permute les changements de {{firstStat} et de {{secondStat}} avec ceux de sa cible !", "switchedTwoStatChanges": "{{pokemonName}} permute les changements de {{firstStat} et de {{secondStat}} avec ceux de sa cible !",
"switchedStat": "{{pokemonName}} et sa cible échangent leur {{stat}} !", "switchedStat": "{{pokemonName}} et sa cible échangent leur {{stat}} !",
"sharedGuard": "{{pokemonName}} additionne sa garde à celle de sa cible et redistribue le tout équitablement !", "sharedGuard": "{{pokemonName}} additionne sa garde à celle de sa cible et redistribue le tout équitablement !",
"sharedPower": "{{pokemonName}} additionne sa force à celle de sa cible et redistribue le tout équitablement !", "sharedPower": "{{pokemonName}} additionne sa force à celle de sa cible et redistribue le tout équitablement !",
"goingAllOutForAttack": "{{pokemonName}} a pris\ncette capacité au sérieux !", "goingAllOutForAttack": "{{pokemonName}} a pris\ncette capacité au sérieux !",
"regainedHealth": "{{pokemonName}}\nrécupère des PV !", "regainedHealth": "{{pokemonName}}\nrécupère des PV !",
"keptGoingAndCrashed": "{{pokemonName}}\nsécrase au sol !", "keptGoingAndCrashed": "{{pokemonName}}\nsécrase au sol !",
@ -22,7 +22,7 @@
"loweredItsHead": "{{pokemonName}}\nbaisse la tête !", "loweredItsHead": "{{pokemonName}}\nbaisse la tête !",
"isGlowing": "{{pokemonName}} est entouré\ndune lumière intense !", "isGlowing": "{{pokemonName}} est entouré\ndune lumière intense !",
"bellChimed": "Un grelot sonne !", "bellChimed": "Un grelot sonne !",
"foresawAnAttack": "{{pokemonName}}\nprévoit une attaque !", "foresawAnAttack": "{{pokemonName}}\nprévoit une attaque !",
"isTighteningFocus": "{{pokemonName}} se concentre\nau maximum !", "isTighteningFocus": "{{pokemonName}} se concentre\nau maximum !",
"hidUnderwater": "{{pokemonName}}\nse cache sous leau !", "hidUnderwater": "{{pokemonName}}\nse cache sous leau !",
"soothingAromaWaftedThroughArea": "Une odeur apaisante flotte dans lair !", "soothingAromaWaftedThroughArea": "Une odeur apaisante flotte dans lair !",
@ -34,7 +34,7 @@
"becameCloakedInFreezingAir": "{{pokemonName}} est entouré\ndun air glacial !", "becameCloakedInFreezingAir": "{{pokemonName}} est entouré\ndun air glacial !",
"isChargingPower": "{{pokemonName}}\nconcentre son énergie !", "isChargingPower": "{{pokemonName}}\nconcentre son énergie !",
"burnedItselfOut": "Le feu intérieur de {{pokemonName}}\nsest entièrement consumé !", "burnedItselfOut": "Le feu intérieur de {{pokemonName}}\nsest entièrement consumé !",
"startedHeatingUpBeak": "{{pokemonName}}\nfait chauffer son bec !", "startedHeatingUpBeak": "{{pokemonName}}\nfait chauffer son bec !",
"setUpShellTrap": "{{pokemonName}} déclenche\nle Carapiège!", "setUpShellTrap": "{{pokemonName}} déclenche\nle Carapiège!",
"isOverflowingWithSpacePower": "La puissance du cosmos afflue dans le corps\nde {{pokemonName}} !", "isOverflowingWithSpacePower": "La puissance du cosmos afflue dans le corps\nde {{pokemonName}} !",
"usedUpAllElectricity": "{{pokemonName}}a utilisé\ntoute son électricité !", "usedUpAllElectricity": "{{pokemonName}}a utilisé\ntoute son électricité !",
@ -66,5 +66,5 @@
"revivalBlessing": "{{pokemonName}} a repris connaissance\net est prêt à se battre de nouveau !", "revivalBlessing": "{{pokemonName}} a repris connaissance\net est prêt à se battre de nouveau !",
"swapArenaTags": "Les effets affectant chaque côté du terrain\nont été échangés par {{pokemonName}} !", "swapArenaTags": "Les effets affectant chaque côté du terrain\nont été échangés par {{pokemonName}} !",
"exposedMove": "{{targetPokemonName}} est identifié\npar {{pokemonName}} !", "exposedMove": "{{targetPokemonName}} est identifié\npar {{pokemonName}} !",
"safeguard": "{{targetName}} est protégé\npar la capacité Rune Protect !" "safeguard": "{{targetName}} est protégé\npar la capacité Rune Protect !"
} }

View File

@ -1,7 +1,7 @@
{ {
"moveset": "Capacités", "moveset": "Capacités",
"gender": "Sexe :", "gender": "Sexe :",
"ability": "Talent :", "ability": "Talent :",
"nature": "Nature :", "nature": "Nature :",
"form": "Forme :" "form": "Forme :"
} }

View File

@ -6,9 +6,9 @@
"ATKshortened": "Atq", "ATKshortened": "Atq",
"DEF": "Défense", "DEF": "Défense",
"DEFshortened": "Déf", "DEFshortened": "Déf",
"SPATK": "Atq. Spé.", "SPATK": "Atq. Spé.",
"SPATKshortened": "AtqSp", "SPATKshortened": "AtqSp",
"SPDEF": "Déf. Spé.", "SPDEF": "Déf. Spé.",
"SPDEFshortened": "DéfSp", "SPDEFshortened": "DéfSp",
"SPD": "Vitesse", "SPD": "Vitesse",
"SPDshortened": "Vit", "SPDshortened": "Vit",

View File

@ -100,7 +100,7 @@
"moveTouchControls": "Déplacer les contrôles tactiles", "moveTouchControls": "Déplacer les contrôles tactiles",
"shopOverlayOpacity": "Opacité boutique", "shopOverlayOpacity": "Opacité boutique",
"shopCursorTarget": "Choix après relance", "shopCursorTarget": "Choix après relance",
"items": "Obj. gratuits", "rewards": "Obj. gratuits",
"reroll": "Relance", "reroll": "Relance",
"shop": "Boutique", "shop": "Boutique",
"checkTeam": "Équipe" "checkTeam": "Équipe"

View File

@ -1,36 +1,36 @@
{ {
"battlesWon": "combats gagnés !", "battlesWon": "combats gagnés !",
"joinTheDiscord": "Rejoins le Discord !", "joinTheDiscord": "Rejoins le Discord !",
"infiniteLevels": "Niveaux infinis !", "infiniteLevels": "Niveaux infinis !",
"everythingStacks": "Tout se cumule !", "everythingStacks": "Tout se cumule !",
"optionalSaveScumming": "Optional Save Scumming!", "optionalSaveScumming": "Optional Save Scumming !",
"biomes": "35 biomes !", "biomes": "35 biomes !",
"openSource": "Open Source !", "openSource": "Open Source !",
"playWithSpeed": "Joue en vitesse x5 !", "playWithSpeed": "Joue en vitesse x5 !",
"liveBugTesting": "Tests de bugs en direct !", "liveBugTesting": "Tests de bugs en direct !",
"heavyInfluence": "Grosse influence de RoR2 !", "heavyInfluence": "Grosse influence de RoR2 !",
"pokemonRiskAndPokemonRain": "Pokémon Risk et Pokémon Rain !", "pokemonRiskAndPokemonRain": "Pokémon Risk et Pokémon Rain !",
"nowWithMoreSalt": "Désormais avec 33% de sel en plus !", "nowWithMoreSalt": "Désormais avec 33% de sel en plus !",
"infiniteFusionAtHome": "Infinite Fusion, chez vous !", "infiniteFusionAtHome": "Infinite Fusion, chez vous !",
"brokenEggMoves": "Des Capacités Œuf craquées !", "brokenEggMoves": "Des Capacités Œuf craquées !",
"magnificent": "Magnifique !", "magnificent": "Magnifique !",
"mubstitute": "Mubstitute !", "mubstitute": "Mubstitute !",
"thatsCrazy": "Cest une dinguerie !", "thatsCrazy": "Cest une dinguerie !",
"oranceJuice": "Jus dorange !", "oranceJuice": "Jus dorange !",
"questionableBalancing": "Équilibrage douteux !", "questionableBalancing": "Équilibrage douteux !",
"coolShaders": "Cool shaders !", "coolShaders": "Cool shaders !",
"aiFree": "Garanti sans IA !", "aiFree": "Garanti sans IA !",
"suddenDifficultySpikes": "De soudains pics de difficultés !", "suddenDifficultySpikes": "De soudains pics de difficultés !",
"basedOnAnUnfinishedFlashGame": "Basé sur un jeu Flash abandonné !", "basedOnAnUnfinishedFlashGame": "Basé sur un jeu Flash abandonné !",
"moreAddictiveThanIntended": "Plus addictif que prévu !", "moreAddictiveThanIntended": "Plus addictif que prévu !",
"mostlyConsistentSeeds": "Des seeds à peu près stables !", "mostlyConsistentSeeds": "Des seeds à peu près stables !",
"achievementPointsDontDoAnything": "Les Points de Succès servent à rien !", "achievementPointsDontDoAnything": "Les Points de Succès servent à rien !",
"youDoNotStartAtLevel": "Ne commence pas au Niveau 2000 !", "youDoNotStartAtLevel": "Ne commence pas au Niveau 2000 !",
"dontTalkAboutTheManaphyEggIncident": "Ne parle pas de lincident de lŒuf de Manaphy !", "dontTalkAboutTheManaphyEggIncident": "Ne parle pas de lincident de lŒuf de Manaphy !",
"alsoTryPokengine": "Essaye aussi Pokéngine !", "alsoTryPokengine": "Essaye aussi Pokéngine !",
"alsoTryEmeraldRogue": "Essaye aussi Emerald Rogue!", "alsoTryEmeraldRogue": "Essaye aussi Emerald Rogue!",
"alsoTryRadicalRed": "Essaye aussi Radical Red !", "alsoTryRadicalRed": "Essaye aussi Radical Red !",
"eeveeExpo": "Eevee Expo !", "eeveeExpo": "Eevee Expo !",
"ynoproject": "YNOproject !", "ynoproject": "YNOproject !",
"breedersInSpace": "Des Éleveurs dans lespace !" "breedersInSpace": "Des Éleveurs dans lespace !"
} }

View File

@ -33,7 +33,7 @@
"obtainSource": "{{pokemonNameWithAffix}} est paralysé\npar {{sourceText}} ! Il aura du mal à attaquer !", "obtainSource": "{{pokemonNameWithAffix}} est paralysé\npar {{sourceText}} ! Il aura du mal à attaquer !",
"activation": "{{pokemonNameWithAffix}} est paralysé !\nIl na pas pu attaquer !", "activation": "{{pokemonNameWithAffix}} est paralysé !\nIl na pas pu attaquer !",
"overlap": "{{pokemonNameWithAffix}} est\ndéjà paralysé.", "overlap": "{{pokemonNameWithAffix}} est\ndéjà paralysé.",
"heal": "{{pokemonNameWithAffix}} nest\nplus paralysé !" "heal": "{{pokemonNameWithAffix}} nest\nplus paralysé !"
}, },
"sleep": { "sleep": {
"name": "Sommeil", "name": "Sommeil",

View File

@ -1,10 +1,10 @@
{ {
"intro": "Bienvenue dans PokéRogue, un fangame axé sur les combats Pokémon avec des éléments roguelite !\n$Ce jeu nest pas monétisé et nous ne prétendons pas à la propriété de Pokémon, ni des éléments sous copyright\n$utilisés.\n$Ce jeu est toujours en développement, mais entièrement jouable.\n$Tout signalement de bugs passe par le serveur Discord.\n$Si le jeu est lent, vérifiez que lAccélération Matérielle est activée dans les paramètres du navigateur.", "intro": "Bienvenue dans PokéRogue, un fangame axé sur les combats Pokémon avec des éléments roguelite !\n$Ce jeu nest pas monétisé et nous ne prétendons à la propriété daucun élément sous copyright utilisé.\n$Bien quen développement permanent, PokéRogue reste entièrement jouable.\n$Tout signalement de bugs et derreurs quelconques passe par le serveur Discord.\n$Si le jeu est lent, vérifiez que lAccélération Matérielle est activée dans les paramètres du navigateur.",
"accessMenu": "Accédez au menu avec M ou Échap lors de lattente dune\naction.\n$Il contient les paramètres et diverses fonctionnalités", "accessMenu": "Accédez au menu avec M ou Échap lors de lattente dune\naction.\n$Il contient les paramètres et diverses fonctionnalités.",
"menu": "Vous pouvez accéder aux paramètres depuis ce menu.\n$Vous pouvez entre autres y changer la vitesse du jeu ou le style de fenêtre.\n$Il y a également toute une variété dautres fonctionnalités,\n$jetez-y un œil !", "menu": "Vous pouvez accéder aux paramètres depuis ce menu.\n$Vous pouvez entre autres y changer la vitesse du jeu ou le style de fenêtre…\n$Mais également des tonnes dautres fonctionnalités, jetez-y un œil !",
"starterSelect": "Choisissez vos starters depuis cet écran avec Z ou Espace.\nIls formeront votre équipe de départ.\n$Chacun possède une valeur. Votre équipe peut avoir jusquà\n6 membres, tant que vous ne dépassez pas un cout de 10.\n$Vous pouvez aussi choisir le sexe, le talent et la forme en\nfonction des variants déjà capturés ou éclos.\n$Les IVs dun starter sont les meilleurs de tous ceux de son\nespèce déjà obtenus. Essayez donc den obtenir plusieurs !", "starterSelect": "Choisissez vos starters depuis cet écran avec Z ou Espace.\nIls formeront votre équipe de départ.\n$Chacun possède une valeur. Votre équipe peut avoir jusquà 6 membres, sans dépasser un cout de 10.\n$Vous pouvez aussi choisir le sexe, le talent et la forme en\nfonction des variants déjà capturés ou éclos.\n$Les IV dun starter sont les meilleurs de tous ceux de son espèce déjà possédés. Obtenez-en plusieurs !",
"pokerus": "Chaque jour, 3 starters tirés aléatoirement ont un contour\n$violet. Si un starter que vous possédez la, essayez de\n$lajouter à votre équipe. Vérifiez bien son résumé !", "pokerus": "Chaque jour, 3 starters tirés aléatoirement ont un contour violet.\n$Si un starter que vous possédez la, essayez de lajouter à votre équipe. Vérifiez bien son résumé !",
"statChange": "Les changements de stats restent à travers les combats tant que le Pokémon nest pas rappelé.\n$Vos Pokémon sont rappelés avant un combat de Dresseur et avant dentrer dans un nouveau biome.\n$Vous pouvez voir en combat les changements de stats dun Pokémon en maintenant C ou Maj.\n$Vous pouvez également voir les capacités de ladversaire en maintenant V.\n$Seules les capacités que le Pokémon a utilisées dans ce combat sont consultables.", "statChange": "Les changements de stats persistent à travers les combats tant que le Pokémon nest pas rappelé.\n$Vos Pokémon sont rappelés avant un combat de Dresseur et avant dentrer dans un nouveau biome.\n$Vous pouvez voir en combat les changements de stats dun Pokémon en maintenant C ou Maj.\n$Vous pouvez également voir les capacités de ladversaire en maintenant V.\n$Seules les capacités que le Pokémon a utilisées dans ce combat sont consultables.",
"selectItem": "Après chaque combat, vous avez le choix entre 3 objets\ntirés au sort. Vous ne pouvez en prendre quun.\n$Cela peut être des objets consommables, des objets à\nfaire tenir, ou des objets passifs aux effets permanents.\n$La plupart des effets des objets non-consommables se cumuleront de diverses manières.\n$Certains objets apparaitront sils peuvent être utilisés, comme les objets dévolution.\n$Vous pouvez aussi transférer des objets tenus entre Pokémon en utilisant loption de transfert.\n$Loption de transfert apparait en bas à droite dès que vous avez obtenu un objet à faire tenir.\n$Vous pouvez acheter des consommables avec de largent.\nPlus vous progressez, plus le choix sera varié.\n$Choisir un des objets gratuits déclenchera le prochain combat, donc faites bien tous vos achats avant.", "selectItem": "Après chaque combat, vous avez le choix entre 3 objets\ntirés au sort. Vous ne pouvez en prendre quun.\n$Cela peut être des objets consommables, des objets à\nfaire tenir, ou des objets passifs aux effets permanents.\n$La plupart des effets des objets non-consommables se cumuleront de diverses manières.\n$Certains objets napparaitront que sils ont une utilité immédiate, comme les objets dévolution.\n$Vous pouvez aussi transférer des objets tenus entre Pokémon en utilisant loption de transfert.\n$Loption de transfert apparait en bas à droite dès quun Pokémon de léquipe porte un objet.\n$Vous pouvez acheter des consommables avec de largent.\nPlus vous progressez, plus le choix sera large.\n$Choisir un des objets gratuits déclenchera le prochain combat, donc faites bien tous vos achats avant.",
"eggGacha": "Depuis cet écran, vous pouvez échanger vos coupons\ncontre des Œufs de Pokémon.\n$Les Œufs éclosent après avoir remporté un certain nombre\nde combats. Les plus rares mettent plus de temps.\n$Les Pokémon éclos ne rejoindront pas votre équipe,\nmais seront ajoutés à vos starters.\n$Les Pokémon issus dŒufs ont généralement de\nmeilleurs IVs que les Pokémon sauvages.\n$Certains Pokémon ne peuvent être obtenus\nque dans des Œufs.\n$Il y a 3 différentes machines à actionner avec différents\nbonus, prenez celle qui vous convient le mieux !" "eggGacha": "Depuis cet écran, vous pouvez utiliser vos coupons\npour recevoir Œufs de Pokémon au hasard.\n$Les Œufs éclosent après avoir remporté un certain nombre de combats. Plus ils sont rares, plus ils mettent de temps.\n$Les Pokémon éclos ne rejoindront pas votre équipe, mais seront ajoutés à vos starters.\n$Les Pokémon issus dŒufs ont généralement de meilleurs IV que les Pokémon sauvages.\n$Certains Pokémon ne peuvent être obtenus que dans des Œufs.\n$Il y a 3 différentes machines à actionner avec différents\nbonus, prenez celle qui vous convient le mieux !"
} }

View File

@ -1,9 +1,9 @@
{ {
"vouchers": "Coupons", "vouchers": "Coupons",
"eggVoucher": "Coupon Œuf", "eggVoucher": "Coupon Œuf",
"eggVoucherPlus": "Coupon Œuf +", "eggVoucherPlus": "Coupon Œuf +",
"eggVoucherPremium": "Coupon Œuf Premium", "eggVoucherPremium": "Coupon Œuf Premium",
"eggVoucherGold": "Coupon Œuf Or", "eggVoucherGold": "Coupon Œuf Or",
"locked": "Verrouillé", "locked": "Verrouillé",
"defeatTrainer": "Vaincre {{trainerName}}" "defeatTrainer": "Vaincre {{trainerName}}"
} }

View File

@ -1,32 +1,32 @@
{ {
"sunnyStartMessage": "Les rayons du soleil brillent !", "sunnyStartMessage": "Les rayons du soleil brillent !",
"sunnyLapseMessage": "Les rayons du soleil brillent fort !", "sunnyLapseMessage": "Les rayons du soleil brillent fort !",
"sunnyClearMessage": "Les rayons du soleil saffaiblissent !", "sunnyClearMessage": "Les rayons du soleil saffaiblissent !",
"rainStartMessage": "Il commence à pleuvoir !", "rainStartMessage": "Il commence à pleuvoir !",
"rainLapseMessage": "La pluie continue de tomber !", "rainLapseMessage": "La pluie continue de tomber !",
"rainClearMessage": "La pluie sest arrêtée !", "rainClearMessage": "La pluie sest arrêtée !",
"sandstormStartMessage": "Une tempête de sable se prépare !", "sandstormStartMessage": "Une tempête de sable se prépare !",
"sandstormLapseMessage": "La tempête de sable fait rage !", "sandstormLapseMessage": "La tempête de sable fait rage !",
"sandstormClearMessage": "La tempête de sable se calme !", "sandstormClearMessage": "La tempête de sable se calme !",
"sandstormDamageMessage": "La tempête de sable inflige des dégâts\nà {{pokemonNameWithAffix}} !", "sandstormDamageMessage": "La tempête de sable inflige des dégâts\nà {{pokemonNameWithAffix}} !",
"hailStartMessage": "Il commence à grêler !", "hailStartMessage": "Il commence à grêler !",
"hailLapseMessage": "La grêle continue de tomber !", "hailLapseMessage": "La grêle continue de tomber !",
"hailClearMessage": "La grêle sest arrêtée !", "hailClearMessage": "La grêle sest arrêtée !",
"hailDamageMessage": "La grêle inflige des dégâts\nà {{pokemonNameWithAffix}} !", "hailDamageMessage": "La grêle inflige des dégâts\nà {{pokemonNameWithAffix}} !",
"snowStartMessage": "Il commence à neiger !", "snowStartMessage": "Il commence à neiger !",
"snowLapseMessage": "Il y a une tempête de neige !", "snowLapseMessage": "Il y a une tempête de neige !",
"snowClearMessage": "La neige sest arrêtée !", "snowClearMessage": "La neige sest arrêtée !",
"fogStartMessage": "Le brouillard devient épais…", "fogStartMessage": "Le brouillard devient épais…",
"fogLapseMessage": "Le brouillard continue !", "fogLapseMessage": "Le brouillard continue !",
"fogClearMessage": "Le brouillard sest dissipé !", "fogClearMessage": "Le brouillard sest dissipé !",
"heavyRainStartMessage": "Une pluie battante sabat soudainement !", "heavyRainStartMessage": "Une pluie battante sabat soudainement !",
"heavyRainLapseMessage": "La pluie battante continue.", "heavyRainLapseMessage": "La pluie battante continue.",
"heavyRainClearMessage": "La pluie battante sest arrêtée…", "heavyRainClearMessage": "La pluie battante sest arrêtée…",
"harshSunStartMessage": "Les rayons du soleil sintensifient !", "harshSunStartMessage": "Les rayons du soleil sintensifient !",
"harshSunLapseMessage": "Les rayons du soleil sont brulants !", "harshSunLapseMessage": "Les rayons du soleil sont brulants !",
"harshSunClearMessage": "Les rayons du soleil saffaiblissent !", "harshSunClearMessage": "Les rayons du soleil saffaiblissent !",
"strongWindsStartMessage": "Un vent mystérieux se lève !", "strongWindsStartMessage": "Un vent mystérieux se lève !",
"strongWindsLapseMessage": "Le vent mystérieux souffle violemment !", "strongWindsLapseMessage": "Le vent mystérieux souffle violemment !",
"strongWindsEffectMessage": "Le courant aérien mystérieux affaiblit lattaque!", "strongWindsEffectMessage": "Le courant aérien mystérieux affaiblit lattaque !",
"strongWindsClearMessage": "Le vent mystérieux sest dissipé…" "strongWindsClearMessage": "Le vent mystérieux sest dissipé…"
} }

View File

@ -11,6 +11,7 @@
"blockItemTheft": "{{abilityName}} di {{pokemonNameWithAffix}}\nlo rende immune ai furti!", "blockItemTheft": "{{abilityName}} di {{pokemonNameWithAffix}}\nlo rende immune ai furti!",
"typeImmunityHeal": "{{pokemonName}} recupera alcuni PS\ncon {{abilityName}}!", "typeImmunityHeal": "{{pokemonName}} recupera alcuni PS\ncon {{abilityName}}!",
"nonSuperEffectiveImmunity": "{{pokemonNameWithAffix}} evita il colpo\ncon {{abilityName}}!", "nonSuperEffectiveImmunity": "{{pokemonNameWithAffix}} evita il colpo\ncon {{abilityName}}!",
"fullHpResistType": "{{pokemonNameWithAffix}} fa risplendere la sua corazza\ne altera i rapporti tra i tipi!",
"disguiseAvoidedDamage": "{{pokemonNameWithAffix}} è stato smascherato!", "disguiseAvoidedDamage": "{{pokemonNameWithAffix}} è stato smascherato!",
"moveImmunity": "Non ha effetto su {{pokemonNameWithAffix}}!", "moveImmunity": "Non ha effetto su {{pokemonNameWithAffix}}!",
"reverseDrain": "{{pokemonNameWithAffix}} ha assorbito la melma!", "reverseDrain": "{{pokemonNameWithAffix}} ha assorbito la melma!",
@ -51,6 +52,7 @@
"postSummonTeravolt": "{{pokemonNameWithAffix}} emana unaura repulsiva!", "postSummonTeravolt": "{{pokemonNameWithAffix}} emana unaura repulsiva!",
"postSummonDarkAura": "Labilità Auratetra di {{pokemonNameWithAffix}} è attiva.", "postSummonDarkAura": "Labilità Auratetra di {{pokemonNameWithAffix}} è attiva.",
"postSummonFairyAura": "Labilità Aurafolletto di {{pokemonNameWithAffix}} è attiva.", "postSummonFairyAura": "Labilità Aurafolletto di {{pokemonNameWithAffix}} è attiva.",
"postSummonAuraBreak": "{{pokemonNameWithAffix}} inverte gli effetti di tutte le aure!",
"postSummonNeutralizingGas": "Il Gas Reagente di {{pokemonNameWithAffix}}\nsi diffonde tuttintorno!", "postSummonNeutralizingGas": "Il Gas Reagente di {{pokemonNameWithAffix}}\nsi diffonde tuttintorno!",
"postSummonAsOneGlastrier": "{{pokemonNameWithAffix}} ha due abilità!", "postSummonAsOneGlastrier": "{{pokemonNameWithAffix}} ha due abilità!",
"postSummonAsOneSpectrier": "{{pokemonNameWithAffix}} ha due abilità!", "postSummonAsOneSpectrier": "{{pokemonNameWithAffix}} ha due abilità!",

View File

@ -36,5 +36,6 @@
"matBlock": "Ribaltappeto", "matBlock": "Ribaltappeto",
"craftyShield": "Truccodifesa", "craftyShield": "Truccodifesa",
"tailwind": "Ventoincoda", "tailwind": "Ventoincoda",
"happyHour": "Cuccagna" "happyHour": "Cuccagna",
"safeguard": "Salvaguardia"
} }

View File

@ -44,6 +44,7 @@
"moveNotImplemented": "{{moveName}} non è ancora implementata e non può essere selezionata.", "moveNotImplemented": "{{moveName}} non è ancora implementata e non può essere selezionata.",
"moveNoPP": "Non ci sono PP rimanenti\nper questa mossa!", "moveNoPP": "Non ci sono PP rimanenti\nper questa mossa!",
"moveDisabled": "{{moveName}} è disabilitata!", "moveDisabled": "{{moveName}} è disabilitata!",
"disableInterruptedMove": "La mossa {{moveName}} di\n{{pokemonNameWithAffix}} è bloccata!",
"noPokeballForce": "Una forza misteriosa\nimpedisce l'uso delle Poké Ball.", "noPokeballForce": "Una forza misteriosa\nimpedisce l'uso delle Poké Ball.",
"noPokeballTrainer": "Non puoi catturare\nPokémon di altri allenatori!", "noPokeballTrainer": "Non puoi catturare\nPokémon di altri allenatori!",
"noPokeballMulti": "Puoi lanciare una Poké Ball\nsolo quando rimane un singolo Pokémon!", "noPokeballMulti": "Puoi lanciare una Poké Ball\nsolo quando rimane un singolo Pokémon!",

View File

@ -67,5 +67,7 @@
"saltCuredLapse": "{{pokemonNameWithAffix}} viene colpito da {{moveName}}!", "saltCuredLapse": "{{pokemonNameWithAffix}} viene colpito da {{moveName}}!",
"cursedOnAdd": "{{pokemonNameWithAffix}} ha sacrificato metà dei suoi PS per\nlanciare una maledizione su {{pokemonName}}!", "cursedOnAdd": "{{pokemonNameWithAffix}} ha sacrificato metà dei suoi PS per\nlanciare una maledizione su {{pokemonName}}!",
"cursedLapse": "{{pokemonNameWithAffix}} subisce la maledizione!", "cursedLapse": "{{pokemonNameWithAffix}} subisce la maledizione!",
"stockpilingOnAdd": "{{pokemonNameWithAffix}} ha usato Accumulo per la\n{{stockpiledCount}}ª volta!" "stockpilingOnAdd": "{{pokemonNameWithAffix}} ha usato Accumulo per la\n{{stockpiledCount}}ª volta!",
"disabledOnAdd": "La mossa {{moveName}} di\n{{pokemonNameWithAffix}} è stata bloccata!",
"disabledLapse": "La mossa {{moveName}} di\n{{pokemonNameWithAffix}} non è più bloccata!"
} }

View File

@ -51,5 +51,7 @@
"renamePokemon": "Rinomina un Pokémon", "renamePokemon": "Rinomina un Pokémon",
"rename": "Rinomina", "rename": "Rinomina",
"nickname": "Nickname", "nickname": "Nickname",
"errorServerDown": "Poffarbacco! C'è stato un errore nella comunicazione col server.\n\nPuoi lasciare questa finestra aperta,\nil gioco si riconnetterà automaticamente." "errorServerDown": "Poffarbacco! C'è stato un errore nella comunicazione col server.\n\nPuoi lasciare questa finestra aperta,\nil gioco si riconnetterà automaticamente.",
"noSaves": "Non ci sono file di salvataggio registrati!",
"tooManySaves": "Ci sono troppi file di salvataggio registrati!"
} }

View File

@ -47,10 +47,14 @@
"description": "Cambia la natura del Pokémon in {{natureName}} e sblocca la natura nel menu degli starter." "description": "Cambia la natura del Pokémon in {{natureName}} e sblocca la natura nel menu degli starter."
}, },
"DoubleBattleChanceBoosterModifierType": { "DoubleBattleChanceBoosterModifierType": {
"description": "Raddoppia la possibilità di imbattersi in doppie battaglie per {{battleCount}} battaglie." "description": "Quadruplica la possibilità di imbattersi in doppie battaglie per {{battleCount}} battaglie."
}, },
"TempStatStageBoosterModifierType": { "TempStatStageBoosterModifierType": {
"description": "Aumenta la statistica {{stat}} di un livello\na tutti i Pokémon nel gruppo per 5 battaglie." "description": "Aumenta la statistica {{stat}} di {{amount}}\na tutti i Pokémon nel gruppo per 5 battaglie",
"extra": {
"stage": "un livello",
"percentage": "30%"
}
}, },
"AttackTypeBoosterModifierType": { "AttackTypeBoosterModifierType": {
"description": "Aumenta la potenza delle mosse di tipo {{moveType}} del 20% per un Pokémon." "description": "Aumenta la potenza delle mosse di tipo {{moveType}} del 20% per un Pokémon."

View File

@ -8,7 +8,7 @@
"moveTouchControls": "Move Touch Controls", "moveTouchControls": "Move Touch Controls",
"shopOverlayOpacity": "Opacità Finestra Negozio", "shopOverlayOpacity": "Opacità Finestra Negozio",
"shopCursorTarget": "Target Cursore Negozio", "shopCursorTarget": "Target Cursore Negozio",
"items": "Oggetti", "rewards": "Oggetti",
"reroll": "Rerolla", "reroll": "Rerolla",
"shop": "Negozio", "shop": "Negozio",
"checkTeam": "Squadra" "checkTeam": "Squadra"

Some files were not shown because too many files have changed in this diff Show More