Merge branch 'beta' into unpause-fusion
2
.github/workflows/eslint.yml
vendored
@ -11,6 +11,8 @@ on:
|
||||
branches:
|
||||
- main # Trigger on pull request events targeting the main branch
|
||||
- beta # Trigger on pull request events targeting the beta branch
|
||||
merge_group:
|
||||
types: [checks_requested]
|
||||
|
||||
jobs:
|
||||
run-linters: # Define a job named "run-linters"
|
||||
|
2
.github/workflows/github-pages.yml
vendored
@ -8,6 +8,8 @@ on:
|
||||
branches:
|
||||
- main
|
||||
- beta
|
||||
merge_group:
|
||||
types: [checks_requested]
|
||||
|
||||
jobs:
|
||||
pages:
|
||||
|
2
.github/workflows/tests.yml
vendored
@ -11,6 +11,8 @@ on:
|
||||
branches:
|
||||
- main # Trigger on pull request events targeting the main branch
|
||||
- beta # Trigger on pull request events targeting the beta branch
|
||||
merge_group:
|
||||
types: [checks_requested]
|
||||
|
||||
jobs:
|
||||
run-tests: # Define a job named "run-tests"
|
||||
|
13
lefthook.yml
@ -2,6 +2,15 @@ pre-commit:
|
||||
parallel: true
|
||||
commands:
|
||||
eslint:
|
||||
glob: '*.{js,jsx,ts,tsx}'
|
||||
glob: "*.{js,jsx,ts,tsx}"
|
||||
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}
|
22
public/images/pokemon/variant/465.json
Normal 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"
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 43 KiB |
@ -1691,8 +1691,8 @@
|
||||
],
|
||||
"465": [
|
||||
0,
|
||||
2,
|
||||
2
|
||||
1,
|
||||
1
|
||||
],
|
||||
"466": [
|
||||
1,
|
||||
@ -3980,6 +3980,11 @@
|
||||
1,
|
||||
1
|
||||
],
|
||||
"465": [
|
||||
0,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"592": [
|
||||
1,
|
||||
1,
|
||||
@ -5690,7 +5695,7 @@
|
||||
"465": [
|
||||
0,
|
||||
1,
|
||||
2
|
||||
1
|
||||
],
|
||||
"466": [
|
||||
2,
|
||||
@ -8008,6 +8013,11 @@
|
||||
1,
|
||||
1
|
||||
],
|
||||
"465": [
|
||||
0,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"592": [
|
||||
1,
|
||||
1,
|
||||
|
@ -8,5 +8,14 @@
|
||||
"bd216b": "21bd69",
|
||||
"31313a": "31313a",
|
||||
"d65a94": "5ad662"
|
||||
},
|
||||
"2": {
|
||||
"5a193a": "752e2e",
|
||||
"31313a": "3d1519",
|
||||
"d65a94": "e67d2f",
|
||||
"3a73ad": "ebc582",
|
||||
"295a84": "ad875a",
|
||||
"bd216b": "b35131",
|
||||
"193a63": "705040"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 34 KiB |
21
public/images/pokemon/variant/back/female/465.json
Normal 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"
|
||||
}
|
||||
}
|
22
public/images/pokemon/variant/female/465.json
Normal 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"
|
||||
}
|
||||
}
|
BIN
public/images/ui/egg_summary_bg.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
public/images/ui/egg_summary_bg_blank.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
public/images/ui/icon_egg_move.png
Normal file
After Width: | Height: | Size: 179 B |
BIN
public/images/ui/legacy/egg_summary_bg.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
public/images/ui/legacy/icon_egg_move.png
Normal file
After Width: | Height: | Size: 179 B |
BIN
public/images/ui/legacy/settings_icon.png
Normal file
After Width: | Height: | Size: 261 B |
BIN
public/images/ui/settings_icon.png
Normal file
After Width: | Height: | Size: 261 B |
@ -130,7 +130,7 @@ export default class BattleScene extends SceneBase {
|
||||
public gameSpeed: integer = 1;
|
||||
public damageNumbersMode: integer = 0;
|
||||
public reroll: boolean = false;
|
||||
public shopCursorTarget: number = ShopCursorTarget.CHECK_TEAM;
|
||||
public shopCursorTarget: number = ShopCursorTarget.REWARDS;
|
||||
public showMovesetFlyout: boolean = true;
|
||||
public showArenaFlyout: boolean = true;
|
||||
public showTimeOfDayWidget: boolean = true;
|
||||
@ -855,7 +855,7 @@ export default class BattleScene extends SceneBase {
|
||||
overrideModifiers(this, false);
|
||||
overrideHeldItems(this, pokemon, false);
|
||||
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++) {
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
return this.currentBattle?.randSeedInt(this, range, min);
|
||||
}
|
||||
@ -1112,7 +1122,8 @@ export default class BattleScene extends SceneBase {
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -2620,7 +2631,7 @@ export default class BattleScene extends SceneBase {
|
||||
if (mods.length < 1) {
|
||||
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))];
|
||||
};
|
||||
modifiers = shuffleModifiers(modifiers);
|
||||
@ -2742,6 +2753,35 @@ export default class BattleScene extends SceneBase {
|
||||
(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)
|
||||
* @param pokemon The (enemy) pokemon
|
||||
|
@ -6,7 +6,7 @@ import Trainer, { TrainerVariant } from "./field/trainer";
|
||||
import { GameMode } from "./game-mode";
|
||||
import { MoneyMultiplierModifier, PokemonHeldItemModifier } from "./modifier/modifier";
|
||||
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 { BattleSpec } from "#enums/battle-spec";
|
||||
import { Moves } from "#enums/moves";
|
||||
@ -31,7 +31,7 @@ export enum BattlerIndex {
|
||||
|
||||
export interface TurnCommand {
|
||||
command: Command;
|
||||
cursor?: integer;
|
||||
cursor?: number;
|
||||
move?: QueuedMove;
|
||||
targets?: BattlerIndex[];
|
||||
skip?: boolean;
|
||||
@ -39,38 +39,40 @@ export interface TurnCommand {
|
||||
}
|
||||
|
||||
interface TurnCommands {
|
||||
[key: integer]: TurnCommand | null
|
||||
[key: number]: TurnCommand | null
|
||||
}
|
||||
|
||||
export default class Battle {
|
||||
protected gameMode: GameMode;
|
||||
public waveIndex: integer;
|
||||
public waveIndex: number;
|
||||
public battleType: BattleType;
|
||||
public battleSpec: BattleSpec;
|
||||
public trainer: Trainer | null;
|
||||
public enemyLevels: integer[] | undefined;
|
||||
public enemyParty: EnemyPokemon[];
|
||||
public seenEnemyPartyMemberIds: Set<integer>;
|
||||
public enemyLevels: number[] | undefined;
|
||||
public enemyParty: EnemyPokemon[] = [];
|
||||
public seenEnemyPartyMemberIds: Set<number> = new Set<number>();
|
||||
public double: boolean;
|
||||
public started: boolean;
|
||||
public enemySwitchCounter: integer;
|
||||
public turn: integer;
|
||||
public started: boolean = false;
|
||||
public enemySwitchCounter: number = 0;
|
||||
public turn: number = 0;
|
||||
public turnCommands: TurnCommands;
|
||||
public playerParticipantIds: Set<integer>;
|
||||
public battleScore: integer;
|
||||
public postBattleLoot: PokemonHeldItemModifier[];
|
||||
public escapeAttempts: integer;
|
||||
public playerParticipantIds: Set<number> = new Set<number>();
|
||||
public battleScore: number = 0;
|
||||
public postBattleLoot: PokemonHeldItemModifier[] = [];
|
||||
public escapeAttempts: number = 0;
|
||||
public lastMove: Moves;
|
||||
public battleSeed: string;
|
||||
private battleSeedState: string | null;
|
||||
public moneyScattered: number;
|
||||
public lastUsedPokeball: PokeballType | null;
|
||||
public playerFaints: number; // The amount of times pokemon on the players side have fainted
|
||||
public enemyFaints: number; // The amount of times pokemon on the enemies side have fainted
|
||||
public battleSeed: string = Utils.randomString(16, true);
|
||||
private battleSeedState: string | null = null;
|
||||
public moneyScattered: number = 0;
|
||||
public lastUsedPokeball: PokeballType | null = null;
|
||||
/** The number of times a Pokemon on the player's side has fainted this battle */
|
||||
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.waveIndex = waveIndex;
|
||||
this.battleType = battleType;
|
||||
@ -79,22 +81,7 @@ export default class Battle {
|
||||
this.enemyLevels = battleType !== BattleType.TRAINER
|
||||
? new Array(double ? 2 : 1).fill(null).map(() => this.getLevelForWave())
|
||||
: trainer?.getPartyLevels(this.waveIndex);
|
||||
this.enemyParty = [];
|
||||
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;
|
||||
this.double = double ?? false;
|
||||
}
|
||||
|
||||
private initBattleSpec(): void {
|
||||
@ -105,7 +92,7 @@ export default class Battle {
|
||||
this.battleSpec = spec;
|
||||
}
|
||||
|
||||
private getLevelForWave(): integer {
|
||||
private getLevelForWave(): number {
|
||||
const levelWaveIndex = this.gameMode.getWaveForDifficulty(this.waveIndex);
|
||||
const baseLevel = 1 + levelWaveIndex / 2 + Math.pow(levelWaveIndex / 25, 2);
|
||||
const bossMultiplier = 1.2;
|
||||
@ -138,7 +125,7 @@ export default class Battle {
|
||||
return rand / value;
|
||||
}
|
||||
|
||||
getBattlerCount(): integer {
|
||||
getBattlerCount(): number {
|
||||
return this.double ? 2 : 1;
|
||||
}
|
||||
|
||||
@ -367,7 +354,13 @@ export default class Battle {
|
||||
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) {
|
||||
return min;
|
||||
}
|
||||
@ -392,7 +385,7 @@ export default class 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);
|
||||
if (config.getEnemyParty) {
|
||||
this.enemyParty = config.getEnemyParty(scene);
|
||||
@ -408,7 +401,7 @@ export class FixedBattleConfig {
|
||||
public double: boolean;
|
||||
public getTrainer: GetTrainerFunc;
|
||||
public getEnemyParty: GetEnemyPartyFunc;
|
||||
public seedOffsetWaveIndex: integer;
|
||||
public seedOffsetWaveIndex: number;
|
||||
|
||||
setBattleType(battleType: BattleType): FixedBattleConfig {
|
||||
this.battleType = battleType;
|
||||
@ -430,7 +423,7 @@ export class FixedBattleConfig {
|
||||
return this;
|
||||
}
|
||||
|
||||
setSeedOffsetWave(seedOffsetWaveIndex: integer): FixedBattleConfig {
|
||||
setSeedOffsetWave(seedOffsetWaveIndex: number): FixedBattleConfig {
|
||||
this.seedOffsetWaveIndex = seedOffsetWaveIndex;
|
||||
return this;
|
||||
}
|
||||
@ -476,7 +469,7 @@ function getRandomTrainerFunc(trainerPool: (TrainerType | TrainerType[])[], rand
|
||||
}
|
||||
|
||||
export interface FixedBattleConfigs {
|
||||
[key: integer]: FixedBattleConfig
|
||||
[key: number]: FixedBattleConfig
|
||||
}
|
||||
/**
|
||||
* Youngster/Lass on 5
|
||||
|
64
src/data/ability.ts
Normal file → Executable file
@ -310,7 +310,7 @@ export class ReceivedMoveDamageMultiplierAbAttr extends PreDefendAbAttr {
|
||||
|
||||
export class ReceivedTypeDamageMultiplierAbAttr extends ReceivedMoveDamageMultiplierAbAttr {
|
||||
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 {
|
||||
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
|
||||
(args[0] as Utils.NumberHolder).value = 0;
|
||||
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 {
|
||||
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 (simulated) {
|
||||
return true;
|
||||
@ -1093,21 +1093,12 @@ export class PostDefendMoveDisableAbAttr extends PostDefendAbAttr {
|
||||
|
||||
this.attacker = attacker;
|
||||
this.move = move;
|
||||
|
||||
attacker.summonData.disabledMove = move.id;
|
||||
attacker.summonData.disabledTurns = 4;
|
||||
this.attacker.addTag(BattlerTagType.DISABLED, 4, 0, pokemon.id);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
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 {
|
||||
@ -1462,7 +1453,7 @@ export class MovePowerBoostAbAttr extends VariableMovePowerAbAttr {
|
||||
|
||||
export class MoveTypePowerBoostAbAttr extends MovePowerBoostAbAttr {
|
||||
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.
|
||||
*/
|
||||
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) {
|
||||
return defender.canAddTag(BattlerTagType.CONFUSED);
|
||||
} 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;
|
||||
@ -5100,9 +5091,9 @@ export function initAbilities() {
|
||||
.ignorable(),
|
||||
new Ability(Abilities.TINTED_LENS, 4)
|
||||
//@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)
|
||||
.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(),
|
||||
new Ability(Abilities.SLOW_START, 4)
|
||||
.attr(PostSummonAddBattlerTagAbAttr, BattlerTagType.SLOW_START, 5),
|
||||
@ -5118,7 +5109,7 @@ export function initAbilities() {
|
||||
.attr(PostWeatherLapseHealAbAttr, 1, WeatherType.HAIL, WeatherType.SNOW)
|
||||
.partial(), // Healing not blocked by Heal Block
|
||||
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(),
|
||||
new Ability(Abilities.SNOW_WARNING, 4)
|
||||
.attr(PostSummonWeatherChangeAbAttr, WeatherType.SNOW)
|
||||
@ -5236,10 +5227,13 @@ export function initAbilities() {
|
||||
new Ability(Abilities.MOXIE, 5)
|
||||
.attr(PostVictoryStatStageChangeAbAttr, Stat.ATK, 1),
|
||||
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)
|
||||
.attr(PostDefendStatStageChangeAbAttr, (target, user, move) => move.category !== MoveCategory.STATUS && (move.type === Type.DARK || move.type === Type.BUG ||
|
||||
move.type === Type.GHOST), Stat.SPD, 1)
|
||||
.attr(PostDefendStatStageChangeAbAttr, (target, user, move) => {
|
||||
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),
|
||||
new Ability(Abilities.MAGIC_BOUNCE, 5)
|
||||
.ignorable()
|
||||
@ -5313,7 +5307,7 @@ export function initAbilities() {
|
||||
.attr(UnsuppressableAbilityAbAttr)
|
||||
.attr(NoFusionAbilityAbAttr),
|
||||
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)
|
||||
.attr(MovePowerBoostAbAttr, (user, target, move) => move.hasFlag(MoveFlags.PULSE_MOVE), 1.5),
|
||||
new Ability(Abilities.GRASS_PELT, 6)
|
||||
@ -5339,8 +5333,10 @@ export function initAbilities() {
|
||||
.attr(FieldMoveTypePowerBoostAbAttr, Type.FAIRY, 4 / 3),
|
||||
new Ability(Abilities.AURA_BREAK, 6)
|
||||
.ignorable()
|
||||
.conditionalAttr(target => target.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.DARK_AURA)), FieldMoveTypePowerBoostAbAttr, Type.DARK, 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)
|
||||
.attr(PostSummonWeatherChangeAbAttr, WeatherType.HEAVY_RAIN)
|
||||
.attr(PostBiomeChangeWeatherChangeAbAttr, WeatherType.HEAVY_RAIN)
|
||||
@ -5368,7 +5364,7 @@ export function initAbilities() {
|
||||
.condition(getSheerForceHitDisableAbCondition())
|
||||
.unimplemented(),
|
||||
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)
|
||||
.attr(ConditionalCritAbAttr, (user, target, move) => target?.status?.effect === StatusEffect.TOXIC || target?.status?.effect === StatusEffect.POISON),
|
||||
new Ability(Abilities.SHIELDS_DOWN, 7)
|
||||
@ -5424,7 +5420,7 @@ export function initAbilities() {
|
||||
.attr(NoFusionAbilityAbAttr)
|
||||
// Add BattlerTagType.DISGUISE if the pokemon is in its disguised form
|
||||
.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) => Utils.toDmgValue(pokemon.getMaxHp() / 8))
|
||||
.attr(PostBattleInitFormChangeAbAttr, () => 0)
|
||||
@ -5469,7 +5465,7 @@ export function initAbilities() {
|
||||
.attr(AllyMoveCategoryPowerBoostAbAttr, [MoveCategory.SPECIAL], 1.3),
|
||||
new Ability(Abilities.FLUFFY, 7)
|
||||
.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(),
|
||||
new Ability(Abilities.DAZZLING, 7)
|
||||
.attr(FieldPriorityMoveImmunityAbAttr)
|
||||
@ -5519,10 +5515,10 @@ export function initAbilities() {
|
||||
new Ability(Abilities.SHADOW_SHIELD, 7)
|
||||
.attr(ReceivedMoveDamageMultiplierAbAttr, (target, user, move) => target.isFullHp(), 0.5),
|
||||
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)
|
||||
//@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)
|
||||
.attr(PostSummonStatStageChangeAbAttr, [ Stat.ATK ], 1, true)
|
||||
.condition(getOncePerBattleCondition(Abilities.INTREPID_SWORD)),
|
||||
@ -5553,7 +5549,11 @@ export function initAbilities() {
|
||||
new Ability(Abilities.STALWART, 8)
|
||||
.attr(BlockRedirectAbAttr),
|
||||
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)
|
||||
.attr(MovePowerBoostAbAttr, (user, target, move) => move.hasFlag(MoveFlags.SOUND_BASED), 1.3)
|
||||
.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)
|
||||
.attr(PostDefendTerrainChangeAbAttr, TerrainType.GRASSY),
|
||||
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)
|
||||
.ignorable(),
|
||||
new Ability(Abilities.ANGER_SHELL, 9)
|
||||
|
@ -39,13 +39,15 @@ export class BattlerTag {
|
||||
public turnCount: number;
|
||||
public sourceMove: Moves;
|
||||
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.lapseTypes = Array.isArray(lapseType) ? lapseType : [ lapseType ];
|
||||
this.turnCount = turnCount;
|
||||
this.sourceMove = sourceMove!; // TODO: is this bang correct?
|
||||
this.sourceId = sourceId;
|
||||
this.isBatonPassable = isBatonPassable;
|
||||
}
|
||||
|
||||
canAdd(pokemon: Pokemon): boolean {
|
||||
@ -96,6 +98,127 @@ export interface TerrainBattlerTag {
|
||||
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.
|
||||
*/
|
||||
@ -206,7 +329,7 @@ export class ShellTrapTag extends BattlerTag {
|
||||
|
||||
export class TrappedTag extends BattlerTag {
|
||||
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 {
|
||||
@ -326,7 +449,7 @@ export class InterruptedTag extends BattlerTag {
|
||||
*/
|
||||
export class ConfusedTag extends BattlerTag {
|
||||
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 {
|
||||
@ -363,7 +486,7 @@ export class ConfusedTag extends BattlerTag {
|
||||
if (pokemon.randSeedInt(3) === 0) {
|
||||
const atk = pokemon.getEffectiveStat(Stat.ATK);
|
||||
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.damageAndUpdate(damage);
|
||||
pokemon.battleData.hitCount++;
|
||||
@ -386,7 +509,7 @@ export class ConfusedTag extends BattlerTag {
|
||||
*/
|
||||
export class DestinyBondTag extends BattlerTag {
|
||||
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;
|
||||
|
||||
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 {
|
||||
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 {
|
||||
@ -808,7 +931,7 @@ export class AquaRingTag extends BattlerTag {
|
||||
/** Tag used to allow moves that interact with {@link Moves.MINIMIZE} to function */
|
||||
export class MinimizeTag extends BattlerTag {
|
||||
constructor() {
|
||||
super(BattlerTagType.MINIMIZED, BattlerTagLapseType.TURN_END, 1, Moves.MINIMIZE, undefined);
|
||||
super(BattlerTagType.MINIMIZED, BattlerTagLapseType.TURN_END, 1, Moves.MINIMIZE);
|
||||
}
|
||||
|
||||
canAdd(pokemon: Pokemon): boolean {
|
||||
@ -1206,7 +1329,7 @@ export class SturdyTag extends BattlerTag {
|
||||
|
||||
export class PerishSongTag extends BattlerTag {
|
||||
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 {
|
||||
@ -1262,7 +1385,7 @@ export class AbilityBattlerTag extends BattlerTag {
|
||||
public ability: Abilities;
|
||||
|
||||
constructor(tagType: BattlerTagType, ability: Abilities, lapseType: BattlerTagLapseType, turnCount: number) {
|
||||
super(tagType, lapseType, turnCount, undefined);
|
||||
super(tagType, lapseType, turnCount);
|
||||
|
||||
this.ability = ability;
|
||||
}
|
||||
@ -1438,7 +1561,7 @@ export class TypeImmuneTag extends BattlerTag {
|
||||
public immuneType: Type;
|
||||
|
||||
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;
|
||||
}
|
||||
@ -1502,7 +1625,7 @@ export class TypeBoostTag extends BattlerTag {
|
||||
|
||||
export class CritBoostTag extends BattlerTag {
|
||||
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 {
|
||||
@ -1594,7 +1717,7 @@ export class CursedTag extends BattlerTag {
|
||||
private sourceIndex: 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);
|
||||
case BattlerTagType.OCTOLOCK:
|
||||
return new OctolockTag(sourceId);
|
||||
case BattlerTagType.DISABLED:
|
||||
return new DisabledTag(sourceId);
|
||||
case BattlerTagType.IGNORE_GHOST:
|
||||
return new ExposedTag(tagType, sourceMove, Type.GHOST, [Type.NORMAL, Type.FIGHTING]);
|
||||
case BattlerTagType.IGNORE_DARK:
|
||||
|
98
src/data/egg-hatch-data.ts
Normal 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();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
@ -15,7 +15,7 @@ export const EGG_SEED = 1073741824;
|
||||
// Rates for specific random properties in 1/x
|
||||
const DEFAULT_SHINY_RATE = 128;
|
||||
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 MANAPHY_EGG_MANAPHY_RATE = 8;
|
||||
const GACHA_EGG_HA_RATE = 192;
|
||||
|
125
src/data/move.ts
@ -757,12 +757,14 @@ export default class Move implements Localizable {
|
||||
|
||||
const fieldAuras = new Set(
|
||||
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(),
|
||||
);
|
||||
for (const aura of fieldAuras) {
|
||||
// The only relevant values are `move` and the `power` holder
|
||||
aura.applyPreAttack(null, null, simulated, null, this, [power]);
|
||||
aura.applyPreAttack(source, null, simulated, target, this, [power]);
|
||||
}
|
||||
|
||||
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 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 {
|
||||
constructor() {
|
||||
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);
|
||||
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;
|
||||
@ -4489,6 +4425,7 @@ export class AddBattlerTagAttr extends MoveEffectAttr {
|
||||
case BattlerTagType.INFATUATED:
|
||||
case BattlerTagType.NIGHTMARE:
|
||||
case BattlerTagType.DROWSY:
|
||||
case BattlerTagType.DISABLED:
|
||||
return -5;
|
||||
case BattlerTagType.SEEDED:
|
||||
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 failIfLastCondition: MoveConditionFunc = (user: Pokemon, target: Pokemon, move: Move) => user.scene.phaseQueue.find(phase => phase instanceof MovePhase) !== undefined;
|
||||
|
||||
export type MoveAttrFilter = (attr: MoveAttr) => boolean;
|
||||
|
||||
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)
|
||||
.attr(FixedDamageAttr, 20),
|
||||
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),
|
||||
new AttackMove(Moves.ACID, Type.POISON, MoveCategory.SPECIAL, 40, 100, 30, 10, 0, 1)
|
||||
.attr(StatStageChangeAttr, [ Stat.SPDEF ], -1)
|
||||
@ -7037,7 +6977,8 @@ export function initMoves() {
|
||||
.attr(StatusEffectAttr, StatusEffect.FREEZE)
|
||||
.target(MoveTarget.ALL_NEAR_ENEMIES),
|
||||
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)
|
||||
.punchingMove(),
|
||||
new StatusMove(Moves.SCARY_FACE, Type.NORMAL, 100, 10, -1, 0, 2)
|
||||
@ -7088,7 +7029,8 @@ export function initMoves() {
|
||||
.windMove()
|
||||
.target(MoveTarget.ALL_NEAR_ENEMIES),
|
||||
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)
|
||||
.attr(MultiHitAttr)
|
||||
.makesContact(false),
|
||||
@ -7106,7 +7048,8 @@ export function initMoves() {
|
||||
.attr(HitHealAttr)
|
||||
.triageMove(),
|
||||
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)
|
||||
.attr(StatStageChangeAttr, [ Stat.ATK ], -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),
|
||||
new StatusMove(Moves.WIDE_GUARD, Type.ROCK, -1, 10, -1, 3, 5)
|
||||
.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)
|
||||
.attr(AverageStatsAttr, [ Stat.DEF, Stat.SPDEF ], "moveTriggers:sharedGuard"),
|
||||
new StatusMove(Moves.POWER_SPLIT, Type.PSYCHIC, -1, 10, -1, 0, 5)
|
||||
@ -7941,7 +7885,8 @@ export function initMoves() {
|
||||
.attr(PositiveStatStagePowerAttr),
|
||||
new StatusMove(Moves.QUICK_GUARD, Type.FIGHTING, -1, 15, -1, 3, 5)
|
||||
.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)
|
||||
.ignoresProtect()
|
||||
.unimplemented(),
|
||||
@ -8112,7 +8057,8 @@ export function initMoves() {
|
||||
new StatusMove(Moves.MAT_BLOCK, Type.FIGHTING, -1, 10, -1, 0, 6)
|
||||
.target(MoveTarget.USER_SIDE)
|
||||
.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)
|
||||
.condition((user, target, move) => user.battleData.berriesEaten.length > 0),
|
||||
new StatusMove(Moves.ROTOTILLER, Type.GROUND, -1, 10, -1, 0, 6)
|
||||
@ -8170,7 +8116,8 @@ export function initMoves() {
|
||||
.triageMove(),
|
||||
new StatusMove(Moves.CRAFTY_SHIELD, Type.FAIRY, -1, 10, -1, 3, 6)
|
||||
.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)
|
||||
.target(MoveTarget.ALL)
|
||||
.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)
|
||||
.unimplemented(),
|
||||
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)
|
||||
.attr(StatStageChangeAttr, [ Stat.ATK ], -1),
|
||||
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)
|
||||
.attr(StatStageChangeAttr, [ Stat.SPATK ], -1),
|
||||
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)
|
||||
.attr(StatStageChangeAttr, [ Stat.SPDEF ], 1)
|
||||
.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)
|
||||
.condition(new FirstMoveCondition()),
|
||||
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)
|
||||
.attr(AddBattlerTagAttr, BattlerTagType.TRAPPED, false, false, 1, 1, true)
|
||||
.makesContact(false),
|
||||
@ -8657,6 +8607,7 @@ export function initMoves() {
|
||||
/* Unused */
|
||||
new SelfStatusMove(Moves.MAX_GUARD, Type.NORMAL, -1, 10, -1, 4, 8)
|
||||
.attr(ProtectAttr)
|
||||
.condition(failIfLastCondition)
|
||||
.ignoresVirtual(),
|
||||
/* End Unused */
|
||||
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)
|
||||
.ignoresProtect(),
|
||||
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.METEOR_ASSAULT, Type.FIGHTING, MoveCategory.PHYSICAL, 150, 100, 5, -1, 0, 8)
|
||||
.attr(RechargeAttr)
|
||||
@ -9123,10 +9075,10 @@ export function initMoves() {
|
||||
.attr(TeraBlastCategoryAttr)
|
||||
.attr(TeraBlastTypeAttr)
|
||||
.attr(TeraBlastPowerAttr)
|
||||
.attr(StatStageChangeAttr, [ Stat.ATK, Stat.SPATK ], -1, true, (user, target, move) => user.isTerastallized() && user.isOfType(Type.STELLAR))
|
||||
.partial(),
|
||||
.attr(StatStageChangeAttr, [ Stat.ATK, Stat.SPATK ], -1, true, (user, target, move) => user.isTerastallized() && user.isOfType(Type.STELLAR)),
|
||||
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)
|
||||
.attr(MissEffectAttr, crashDamageFunc)
|
||||
.attr(NoEffectAttr, crashDamageFunc)
|
||||
@ -9318,7 +9270,8 @@ export function initMoves() {
|
||||
.attr(PreMoveMessageAttr, doublePowerChanceMessageFunc)
|
||||
.attr(DoublePowerChanceAttr),
|
||||
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)
|
||||
.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)
|
||||
|
@ -64,6 +64,7 @@ export enum BattlerTagType {
|
||||
STOCKPILING = "STOCKPILING",
|
||||
RECEIVE_DOUBLE_DAMAGE = "RECEIVE_DOUBLE_DAMAGE",
|
||||
ALWAYS_GET_HIT = "ALWAYS_GET_HIT",
|
||||
DISABLED = "DISABLED",
|
||||
IGNORE_GHOST = "IGNORE_GHOST",
|
||||
IGNORE_DARK = "IGNORE_DARK",
|
||||
GULP_MISSILE_ARROKUDA = "GULP_MISSILE_ARROKUDA",
|
||||
|
@ -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 {
|
||||
/** Cursor points to Reroll */
|
||||
/** Cursor points to Reroll row */
|
||||
REROLL,
|
||||
/** Cursor points to Items */
|
||||
ITEMS,
|
||||
/** Cursor points to Shop */
|
||||
/** Cursor points to Rewards row */
|
||||
REWARDS,
|
||||
/** Cursor points to Shop row */
|
||||
SHOP,
|
||||
/** Cursor points to Check Team */
|
||||
/** Cursor points to Check Team row */
|
||||
CHECK_TEAM
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ import { initMoveAnim, loadMoveAnimAssets } from "../data/battle-anims";
|
||||
import { Status, StatusEffect, getRandomStatus } from "../data/status-effect";
|
||||
import { pokemonEvolutions, pokemonPrevolutions, SpeciesFormEvolution, SpeciesEvolutionCondition, FusionSpeciesFormEvolution } from "../data/pokemon-evolutions";
|
||||
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 { 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";
|
||||
@ -1720,7 +1720,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.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.fusionVariant = this.variant;
|
||||
|
||||
@ -2278,7 +2278,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
|
||||
if (!isTypeImmune) {
|
||||
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)
|
||||
* stabMultiplier.value
|
||||
* typeMultiplier
|
||||
@ -2660,11 +2660,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
}
|
||||
|
||||
for (const tag of source.summonData.tags) {
|
||||
|
||||
// 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)) {
|
||||
if (!tag.isBatonPassable) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -2674,6 +2670,33 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
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[] {
|
||||
return this.battleSummonData.moveHistory;
|
||||
}
|
||||
@ -3425,12 +3448,30 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||
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 {
|
||||
return this.scene.currentBattle
|
||||
? this.scene.randBattleSeedInt(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 {
|
||||
return this.randSeedInt((max - min) + 1, min);
|
||||
}
|
||||
@ -4465,8 +4506,6 @@ export interface AttackMoveResult {
|
||||
export class PokemonSummonData {
|
||||
public statStages: number[] = [ 0, 0, 0, 0, 0, 0, 0 ];
|
||||
public moveQueue: QueuedMove[] = [];
|
||||
public disabledMove: Moves = Moves.NONE;
|
||||
public disabledTurns: number = 0;
|
||||
public tags: BattlerTag[] = [];
|
||||
public abilitySuppressed: boolean = false;
|
||||
public abilitiesApplied: Abilities[] = [];
|
||||
@ -4547,7 +4586,7 @@ export type DamageResult = HitResult.EFFECTIVE | HitResult.SUPER_EFFECTIVE | Hit
|
||||
* It links to {@linkcode Move} class via the move ID.
|
||||
* Compared to {@linkcode Move}, this class also tracks if a move has received.
|
||||
* 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 usePp} - removes a point of PP from the move.
|
||||
* @see {@linkcode getMovePp} - returns amount of PP a move currently has.
|
||||
@ -4567,11 +4606,25 @@ export class PokemonMove {
|
||||
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 (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 {
|
||||
|
@ -78,6 +78,7 @@ export class LoadingScene extends SceneBase {
|
||||
this.loadAtlas("overlay_hp_boss", "ui");
|
||||
this.loadImage("overlay_exp", "ui");
|
||||
this.loadImage("icon_owned", "ui");
|
||||
this.loadImage("icon_egg_move", "ui");
|
||||
this.loadImage("ability_bar_left", "ui");
|
||||
this.loadImage("bgm_bar", "ui");
|
||||
this.loadImage("party_exp_bar", "ui");
|
||||
@ -164,6 +165,7 @@ export class LoadingScene extends SceneBase {
|
||||
this.loadImage("saving_icon", "ui");
|
||||
this.loadImage("discord", "ui");
|
||||
this.loadImage("google", "ui");
|
||||
this.loadImage("settings_icon", "ui");
|
||||
|
||||
this.loadImage("default_bg", "arenas");
|
||||
// Load arena images
|
||||
@ -272,6 +274,7 @@ export class LoadingScene extends SceneBase {
|
||||
this.loadImage("gacha_knob", "egg");
|
||||
|
||||
this.loadImage("egg_list_bg", "ui");
|
||||
this.loadImage("egg_summary_bg", "ui");
|
||||
|
||||
this.loadImage("end_m", "cg");
|
||||
this.loadImage("end_f", "cg");
|
||||
|
@ -36,5 +36,6 @@
|
||||
"matBlock": "Tatami-Schild",
|
||||
"craftyShield": "Trickschutz",
|
||||
"tailwind": "Rückenwind",
|
||||
"happyHour": "Goldene Zeiten"
|
||||
}
|
||||
"happyHour": "Goldene Zeiten",
|
||||
"safeguard": "Bodyguard"
|
||||
}
|
||||
|
@ -100,7 +100,7 @@
|
||||
"moveTouchControls": "Bewegung Touch Steuerung",
|
||||
"shopOverlayOpacity": "Shop Overlay Deckkraft",
|
||||
"shopCursorTarget": "Shop-Cursor Ziel",
|
||||
"items": "Items",
|
||||
"rewards": "Items",
|
||||
"reroll": "Neu rollen",
|
||||
"shop": "Shop",
|
||||
"checkTeam": "Team überprüfen"
|
||||
|
@ -52,6 +52,7 @@
|
||||
"postSummonTeravolt": "{{pokemonNameWithAffix}} is radiating a bursting aura!",
|
||||
"postSummonDarkAura": "{{pokemonNameWithAffix}} is radiating a Dark 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!",
|
||||
"postSummonAsOneGlastrier": "{{pokemonNameWithAffix}} has two Abilities!",
|
||||
"postSummonAsOneSpectrier": "{{pokemonNameWithAffix}} has two Abilities!",
|
||||
|
@ -39,5 +39,6 @@
|
||||
"matBlock": "Mat Block",
|
||||
"craftyShield": "Crafty Shield",
|
||||
"tailwind": "Tailwind",
|
||||
"happyHour": "Happy Hour"
|
||||
}
|
||||
"happyHour": "Happy Hour",
|
||||
"safeguard": "Safeguard"
|
||||
}
|
@ -47,5 +47,11 @@
|
||||
"tailwindOnRemovePlayer": "Your team's Tailwind petered out!",
|
||||
"tailwindOnRemoveEnemy": "The opposing team's Tailwind petered out!",
|
||||
"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!"
|
||||
}
|
@ -44,6 +44,7 @@
|
||||
"moveNotImplemented": "{{moveName}} is not yet implemented and cannot be selected.",
|
||||
"moveNoPP": "There's no PP left for\nthis move!",
|
||||
"moveDisabled": "{{moveName}} is disabled!",
|
||||
"disableInterruptedMove": "{{pokemonNameWithAffix}}'s {{moveName}}\nis disabled!",
|
||||
"noPokeballForce": "An unseen force\nprevents using Poké Balls.",
|
||||
"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!",
|
||||
@ -61,6 +62,7 @@
|
||||
"skipItemQuestion": "Are you sure you want to skip taking an item?",
|
||||
"itemStackFull": "The stack for {{fullItemName}} is full.\nYou will receive {{itemName}} instead.",
|
||||
"eggHatching": "Oh?",
|
||||
"eggSkipPrompt": "Skip to egg summary?",
|
||||
"ivScannerUseQuestion": "Use IV Scanner on {{pokemonName}}?",
|
||||
"wildPokemonWithAffix": "Wild {{pokemonName}}",
|
||||
"foePokemonWithAffix": "Foe {{pokemonName}}",
|
||||
|
@ -67,5 +67,7 @@
|
||||
"saltCuredLapse": "{{pokemonNameWithAffix}} is hurt by {{moveName}}!",
|
||||
"cursedOnAdd": "{{pokemonNameWithAffix}} cut its own HP and put a curse on the {{pokemonName}}!",
|
||||
"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."
|
||||
}
|
||||
|
@ -413,7 +413,7 @@
|
||||
},
|
||||
"ariana": {
|
||||
"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",
|
||||
"3": "Your trip ends here. I'm going to take you down!"
|
||||
},
|
||||
|
@ -51,5 +51,7 @@
|
||||
"renamePokemon": "Rename Pokémon",
|
||||
"rename": "Rename",
|
||||
"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!"
|
||||
}
|
@ -65,5 +65,6 @@
|
||||
"suppressAbilities": "{{pokemonName}}'s ability\nwas suppressed!",
|
||||
"revivalBlessing": "{{pokemonName}} was revived!",
|
||||
"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!"
|
||||
}
|
@ -100,7 +100,7 @@
|
||||
"moveTouchControls": "Move Touch Controls",
|
||||
"shopOverlayOpacity": "Shop Overlay Opacity",
|
||||
"shopCursorTarget": "Shop Cursor Target",
|
||||
"items": "Items",
|
||||
"rewards": "Rewards",
|
||||
"reroll": "Reroll",
|
||||
"shop": "Shop",
|
||||
"checkTeam": "Check Team"
|
||||
|
@ -1,21 +1,21 @@
|
||||
{
|
||||
"activeBattleEffects": "Efectos de Terreno Activos",
|
||||
"activeBattleEffects": "Efectos de terreno activos",
|
||||
"player": "Jugador",
|
||||
"neutral": "Neutral",
|
||||
"enemy": "Enemigo",
|
||||
"sunny": "Sol",
|
||||
"rain": "Lluvia",
|
||||
"sandstorm": "Tormenta de Arena",
|
||||
"sandstorm": "Tormenta de arena",
|
||||
"hail": "Granizo",
|
||||
"snow": "Nieve",
|
||||
"fog": "Niebla",
|
||||
"heavyRain": "Diluvio",
|
||||
"harshSun": "Sol Abrasador",
|
||||
"harshSun": "Sol abrasador",
|
||||
"strongWinds": "Turbulencias",
|
||||
"misty": "Campo de Niebla",
|
||||
"electric": "Campo Eléctrico",
|
||||
"grassy": "Campo de Hierba",
|
||||
"psychic": "Campo Psíquico",
|
||||
"misty": "Campo de niebla",
|
||||
"electric": "Campo eléctrico",
|
||||
"grassy": "Campo de hierba",
|
||||
"psychic": "Campo psíquico",
|
||||
"mudSport": "Chapoteo Lodo",
|
||||
"waterSport": "Hidrochorro",
|
||||
"spikes": "Púas",
|
||||
@ -36,5 +36,6 @@
|
||||
"matBlock": "Escudo Tatami",
|
||||
"craftyShield": "Truco Defensa",
|
||||
"tailwind": "Viento Afín",
|
||||
"happyHour": "Paga Extra"
|
||||
}
|
||||
"happyHour": "Paga Extra",
|
||||
"safeguard": "Velo Sagrado"
|
||||
}
|
||||
|
@ -1,4 +1,53 @@
|
||||
{
|
||||
"yourTeam": "tu equipo",
|
||||
"opposingTeam": "el equipo rival",
|
||||
"arenaOnRemove": "Los efectos de {{moveName}} desaparecieron.",
|
||||
"arenaOnRemovePlayer": "Los efectos de {{moveName}}\ndesaparecieron en tu bando.",
|
||||
"arenaOnRemoveEnemy": "Los efectos de {{moveName}}\ndesaparecieron en el bando rival.",
|
||||
"mistOnAdd": "¡Neblina de {{pokemonNameWithAffix}}\nha cubierto a su equipo!",
|
||||
"mistApply": "¡La neblina evita los cambios de estadísticas!",
|
||||
"reflectOnAdd": "¡Reflejo redujo el daño físico!",
|
||||
"reflectOnAddPlayer": "¡Reflejo redujo el daño físico en tu bando!",
|
||||
"reflectOnAddEnemy": "Reflejo redujo el daño físico en el bando rival.",
|
||||
"lightScreenOnAdd": "¡Pantalla de Luz redujo el daño físico!",
|
||||
"lightScreenOnAddPlayer": "¡Pantalla de Luz redujo el daño físico en tu bando!",
|
||||
"lightScreenOnAddEnemy": "¡Pantalla de Luz redujo el daño físico en el bando enemigo!",
|
||||
"auroraVeilOnAdd": "¡Velo Aurora redujo el daño físico!",
|
||||
"auroraVeilOnAddPlayer": "¡Velo Aurora redujo el daño físico en tu bando!",
|
||||
"auroraVeilOnAddEnemy": "¡Velo Aurora redujo el daño físico en el bando rival!",
|
||||
"conditionalProtectOnAdd": "¡{{moveName}} protege a su bando!",
|
||||
"conditionalProtectOnAddPlayer": "¡{{moveName}} protege a tu bando!",
|
||||
"conditionalProtectOnAddEnemy": "¡{{moveName}} protege al bando rival!",
|
||||
"conditionalProtectApply": "¡{{pokemonNameWithAffix}} ha sido protegido por {{moveName}}!",
|
||||
"matBlockOnAdd": "¡{{pokemonNameWithAffix}} va a usar un tatami para bloquear ataques!",
|
||||
"noCritOnAddPlayer": "¡{{moveName}} protege a tu bando de golpes críticos!",
|
||||
"noCritOnAddEnemy": "¡{{moveName}} protege al bando rival de golpes críticos!",
|
||||
"noCritOnRemove": "¡Los efectos de {{moveName}} de {{pokemonNameWithAffix}} se han disipado!",
|
||||
"wishTagOnAdd": "¡El deseo de {{pokemonNameWithAffix}} se ha hecho realidad!",
|
||||
"mudSportOnAdd": "¡Se han debilitado los ataques de tipo Eléctrico!",
|
||||
"mudSportOnRemove": "Chapoteo Lodo ha dejado de surtir efecto.",
|
||||
"waterSportOnAdd": "¡Se han debilitado los ataques\nde tipo Fuego!",
|
||||
"waterSportOnRemove": "Hidrochorro ha dejado de surtir efecto.",
|
||||
"spikesOnAdd": "¡El equipo de {{opponentDesc}} ha sido rodeado por {{moveName}}!",
|
||||
"spikesActivateTrap": "¡Las púas han herido a {{pokemonNameWithAffix}}!",
|
||||
"toxicSpikesOnAdd": "¡El equipo de {{opponentDesc}} ha sido rodeado por {{moveName}}!",
|
||||
"toxicSpikesActivateTrapPoison": "¡{{pokemonNameWithAffix}} ha sido herido por {{moveName}}!",
|
||||
"stealthRockOnAdd": "¡El equipo de {{opponentDesc}} ha sido rodeado por piedras puntiagudas!",
|
||||
"stealthRockActivateTrap": "¡Unas piedras puntiagudas han dañado a {{pokemonNameWithAffix}}!",
|
||||
"stickyWebOnAdd": "¡Una {{moveName}} se extiende a los pies del bando rival!",
|
||||
"stickyWebActivateTrap": "¡{{pokemonName}} ha caído en una red viscosa!",
|
||||
"trickRoomOnAdd": "¡{{pokemonNameWithAffix}} ha alterado las dimensiones!",
|
||||
"trickRoomOnRemove": "Se han restaurado las dimensiones alteradas.",
|
||||
"gravityOnAdd": "¡La gravedad se ha incrementado!",
|
||||
"gravityOnRemove": "La gravedad ha vuelto a su estado normal.",
|
||||
"tailwindOnAdd": "¡Sopla un viento afín!",
|
||||
"tailwindOnAddPlayer": "¡El viento sopla a favor de tu bando!",
|
||||
"tailwindOnAddEnemy": "¡El viento sopla a favor del bando rival!",
|
||||
"tailwindOnRemove": "Ha dejado de soplar el viento afín.",
|
||||
"tailwindOnRemovePlayer": "Ha dejado de soplar el viento que favorecía a tu equipo.",
|
||||
"tailwindOnRemoveEnemy": "Ha dejado de soplar el viento que favorecía al bando rival.",
|
||||
"happyHourOnAdd": "¡La felicidad se respira en el aire!",
|
||||
"happyHourOnRemove": "La felicidad ya no se respira en el aire.",
|
||||
"safeguardOnAdd": "¡Todos los Pokémon están protegidos por Velo Sagrado!",
|
||||
"safeguardOnAddPlayer": "¡Tu equipo se ha protegido con Velo Sagrado!",
|
||||
"safeguardOnAddEnemy": "¡El equipo enemigo se ha protegido con Velo Sagrado!",
|
||||
|
@ -1 +1,71 @@
|
||||
{}
|
||||
{
|
||||
"trappedDesc": "trampa",
|
||||
"flinchedDesc": "retroceso",
|
||||
"confusedDesc": "confusión",
|
||||
"infatuatedDesc": "enamoramiento",
|
||||
"seedDesc": "drenado",
|
||||
"nightmareDesc": "pesadillas",
|
||||
"ingrainDesc": "raíces",
|
||||
"drowsyDesc": "sueño",
|
||||
"rechargingLapse": "¡{{pokemonNameWithAffix}} necesita\nrecuperarse de su ataque!",
|
||||
"trappedOnAdd": "¡{{pokemonNameWithAffix}} no puede escapar!",
|
||||
"trappedOnRemove": "¡{{pokemonNameWithAffix}} se ha\nliberado de {{moveName}}!",
|
||||
"flinchedLapse": "¡{{pokemonNameWithAffix}} se amedrentó!",
|
||||
"confusedOnAdd": "¡{{pokemonNameWithAffix}} se encuentra confuso!",
|
||||
"confusedOnRemove": "¡{{pokemonNameWithAffix}} ya no está confuso!",
|
||||
"confusedOnOverlap": "¡{{pokemonNameWithAffix}} ya está confuso!",
|
||||
"confusedLapse": "¡{{pokemonNameWithAffix}} está confuso!",
|
||||
"confusedLapseHurtItself": "¡Está tan confuso que se ha herido a sí mismo!",
|
||||
"destinyBondLapseIsBoss": "Mismo Destino no afecta a {{pokemonNameWithAffix}}.",
|
||||
"destinyBondLapse": "¡{{pokemonNameWithAffix2}} ha sufrido\nel mismo destino que {{pokemonNameWithAffix}}!",
|
||||
"infatuatedOnAdd": "¡{{pokemonNameWithAffix}} se ha enamorado\nde {{sourcePokemonName}}!",
|
||||
"infatuatedOnOverlap": "¡{{pokemonNameWithAffix}} ya está enamorado!",
|
||||
"infatuatedLapse": "¡{{pokemonNameWithAffix}} se ha enamorado\ndebido a {{sourcePokemonName}}!",
|
||||
"infatuatedLapseImmobilize": "¡El enamoramiento impide que\n{{pokemonNameWithAffix}} reaccione!",
|
||||
"infatuatedOnRemove": "{{pokemonNameWithAffix}} ya no está enamorado.",
|
||||
"seededOnAdd": "¡{{pokemonNameWithAffix}} ha sido infectado!",
|
||||
"seededLapse": "¡Las drenadoras han restado salud a {{pokemonNameWithAffix}}!",
|
||||
"seededLapseShed": "¡{{pokemonNameWithAffix}} ha absorbido el lodo líquido!",
|
||||
"nightmareOnAdd": "¡{{pokemonNameWithAffix}} se ha sumido en una pesadilla!",
|
||||
"nightmareOnOverlap": "¡{{pokemonNameWithAffix}} ya está teniendo pesadillas!",
|
||||
"nightmareLapse": "¡{{pokemonNameWithAffix}} sufre pesadillas!",
|
||||
"encoreOnAdd": "¡{{pokemonNameWithAffix}} sufre los efectos de Otra Vez!",
|
||||
"encoreOnRemove": "¡{{pokemonNameWithAffix}} ya no sufre los efectos de Otra Vez!",
|
||||
"helpingHandOnAdd": "¡{{pokemonNameWithAffix}} se prepara\npara ayudar a {{pokemonName}}!",
|
||||
"ingrainLapse": "¡{{pokemonNameWithAffix}} ha absorbido\nnutrientes a través de sus raíces!",
|
||||
"ingrainOnTrap": "¡{{pokemonNameWithAffix}} ha echado raíces!",
|
||||
"aquaRingOnAdd": "¡{{pokemonNameWithAffix}} se ha rodeado de un manto de agua!",
|
||||
"aquaRingLapse": "¡{{pokemonName}} restauró sus PS con {{moveName}}!",
|
||||
"drowsyOnAdd": "¡{{pokemonNameWithAffix}} empieza a tener sueño!",
|
||||
"damagingTrapLapse": "¡{{moveName}} hiere a {{pokemonNameWithAffix}}!",
|
||||
"bindOnTrap": "¡{{moveName}} de {{sourcePokemonName}} oprime a {{pokemonNameWithAffix}}!",
|
||||
"wrapOnTrap": "¡{{sourcePokemonName}} ha atrapado a {{pokemonNameWithAffix}} con una constricción!",
|
||||
"vortexOnTrap": "¡{{pokemonNameWithAffix}} no puede salir del torbellino!",
|
||||
"clampOnTrap": "¡{{sourcePokemonNameWithAffix}} ha atenazado a \n{{pokemonName}}!",
|
||||
"sandTombOnTrap": "¡{{pokemonNameWithAffix}} ha sido atrapado por {{moveName}}!",
|
||||
"magmaStormOnTrap": "¡La lluvia ígnea cae sobre {{pokemonNameWithAffix}}!",
|
||||
"snapTrapOnTrap": "¡{{pokemonNameWithAffix}} cayó en un cepo!",
|
||||
"thunderCageOnTrap": "¡{{sourcePokemonNameWithAffix}} ha enjaulado a {{pokemonNameWithAffix}}!",
|
||||
"infestationOnTrap": "¡{{pokemonNameWithAffix}} es presa del acoso de {{sourcePokemonNameWithAffix}}!",
|
||||
"protectedOnAdd": "{{pokemonNameWithAffix}}\nse está protegiendo.",
|
||||
"protectedLapse": "¡{{pokemonNameWithAffix}}\nse ha protegido!",
|
||||
"enduringOnAdd": "{{pokemonNameWithAffix}} se prepara para resistir los ataques...",
|
||||
"enduringLapse": "¡{{pokemonNameWithAffix}} ha encajado el golpe!",
|
||||
"sturdyLapse": "¡{{pokemonNameWithAffix}} ha encajado el golpe!",
|
||||
"perishSongLapse": "La cuenta atrás de Canto Mortal de\n{{pokemonNameWithAffix}} ha bajado a {{turnCount}}.",
|
||||
"centerOfAttentionOnAdd": "¡{{pokemonNameWithAffix}} es el centro de atención!",
|
||||
"truantLapse": "{{pokemonNameWithAffix}} está holgazaneando...",
|
||||
"slowStartOnAdd": "¡{{pokemonNameWithAffix}} no está dando todo de sí!",
|
||||
"slowStartOnRemove": "¡{{pokemonNameWithAffix}} ya puede darlo todo!",
|
||||
"highestStatBoostOnAdd": "¡{{pokemonNameWithAffix}} ha reforzado su {{statName}}!",
|
||||
"highestStatBoostOnRemove": "¡Los efectos de {{abilityName}}\nde {{pokemonNameWithAffix}} han desaparecido!",
|
||||
"magnetRisenOnAdd": "¡{{pokemonNameWithAffix}} levita gracias a un campo electromagnético!",
|
||||
"magnetRisenOnRemove": "¡El campo electromagnético de {{pokemonNameWithAffix}} se ha disipado!",
|
||||
"critBoostOnAdd": "¡{{pokemonNameWithAffix}} se está preparando para luchar!",
|
||||
"critBoostOnRemove": "{{pokemonNameWithAffix}} se ha relajado.",
|
||||
"saltCuredOnAdd": "¡{{pokemonNameWithAffix}} está en salazón!",
|
||||
"saltCuredLapse": "¡{{moveName}} ha herido a {{pokemonNameWithAffix}}!",
|
||||
"cursedOnAdd": "¡{{pokemonNameWithAffix}} sacrifica algunos PS y maldice a {{pokemonName}}!",
|
||||
"cursedLapse": "¡{{pokemonNameWithAffix}} es víctima de una maldición!",
|
||||
"stockpilingOnAdd": "¡{{pokemonNameWithAffix}} ha reservado energía por {{stockpiledCount}}ª vez!"
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
{
|
||||
"classic": "Clásica",
|
||||
"endless": "Infinita",
|
||||
"endlessSpliced": "Infinita (Fusión)",
|
||||
"dailyRun": "Diaria",
|
||||
"unknown": "Desconicido",
|
||||
"classic": "Clásico",
|
||||
"endless": "Infinito",
|
||||
"endlessSpliced": "Infinito (Fusión)",
|
||||
"dailyRun": "Diario",
|
||||
"unknown": "Desconocido",
|
||||
"challenge": "Desafío"
|
||||
}
|
||||
}
|
||||
|
@ -14,14 +14,14 @@
|
||||
"register": "Registrarse",
|
||||
"emptyUsername": "El usuario no puede estar vacío",
|
||||
"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",
|
||||
"invalidRegisterPassword": "La contraseña debe tener 6 o más caracteres.",
|
||||
"usernameAlreadyUsed": "El usuario ya está en uso",
|
||||
"accountNonExistent": "El usuario no existe",
|
||||
"unmatchingPassword": "La contraseña no coincide",
|
||||
"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.",
|
||||
"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.",
|
||||
|
@ -1,4 +1,9 @@
|
||||
{
|
||||
"SEND_OUT": "Enviar",
|
||||
"SUMMARY": "Resumen",
|
||||
"CANCEL": "Cancelar",
|
||||
"RELEASE": "Liberar",
|
||||
"APPLY": "Aplicar",
|
||||
"TEACH": "Enseñar",
|
||||
"SPLICE": "Fusionar",
|
||||
"UNSPLICE": "Separar",
|
||||
@ -7,23 +12,23 @@
|
||||
"TRANSFER": "Transferir",
|
||||
"ALL": "Todo",
|
||||
"PASS_BATON": "Relevo",
|
||||
"UNPAUSE_EVOLUTION": "Reanudar Evolución",
|
||||
"UNPAUSE_EVOLUTION": "Reanudar evolución",
|
||||
"REVIVE": "Revivir",
|
||||
"RENAME": "Rename",
|
||||
"choosePokemon": "Elige a un Pokémon.",
|
||||
"doWhatWithThisPokemon": "¿Que quieres hacer con este Pokémon?",
|
||||
"noEnergy": "¡A {{pokemonName}} no le quedan\nfuerzas para luchar!",
|
||||
"hasEnergy": "¡A {{pokemonName}} le quedan\nfuerzas para luchar!",
|
||||
"cantBeUsed": "¡{{pokemonName}} no puede usarse\nen este desafío!",
|
||||
"tooManyItems": "¡{{pokemonName}} tiene demasiados\nde este objeto!",
|
||||
"noEnergy": "¡A {{pokemonName}} no le\nquedan fuerzas para luchar!",
|
||||
"hasEnergy": "¡A {{pokemonName}} le\nquedan fuerzas para luchar!",
|
||||
"cantBeUsed": "¡{{pokemonName}} no puede usarse en este desafío!",
|
||||
"tooManyItems": "¡{{pokemonName}} tiene\ndemasiado de este objeto!",
|
||||
"anyEffect": "No tendría ningún efecto.",
|
||||
"unpausedEvolutions": "Se reanudó las evoluciones de {{pokemonName}}.",
|
||||
"unpausedEvolutions": "Se reanudaron las evoluciones de {{pokemonName}}.",
|
||||
"unspliceConfirmation": "¿Seguro que quiere separar a {{fusionName}}\nde {{pokemonName}}? {{fusionName}} se perderá.",
|
||||
"wasReverted": "{{fusionName}} se revirtió a {{pokemonName}}.",
|
||||
"releaseConfirmation": "¿Quieres liberar a {{pokemonName}}?",
|
||||
"releaseInBattle": "¡No puedes liberar un Pokémon que está en batalla!",
|
||||
"selectAMove": "Selecciona un movimiento.",
|
||||
"changeQuantity": "Selecciona un objeto equipado para transferir.\nUsa < y > para cambiar la cantidad.",
|
||||
"changeQuantity": "Selecciona un ítem para transferir.\nUsa < y > para calibrar.",
|
||||
"selectAnotherPokemonToSplice": "Selecciona otro Pokémon para fusionar.",
|
||||
"cancel": "Salir",
|
||||
"able": "Apto",
|
||||
@ -36,7 +41,7 @@
|
||||
"thisIsWhereWePart": "¡Aquí es donde nos despedimos, {{pokemonName}}!",
|
||||
"illMissYou": "¡Te echaré de menos, {{pokemonName}}!",
|
||||
"illNeverForgetYou": "¡Nunca te olvidaré, {{pokemonName}}!",
|
||||
"untilWeMeetAgain": "¡Hasta que nos volvamos a encontrar, {{pokemonName}}!",
|
||||
"untilWeMeetAgain": "¡Hasta que nos volvamos a\nencontrar, {{pokemonName}}!",
|
||||
"sayonara": "¡Sayonara, {{pokemonName}}!",
|
||||
"smellYaLater": "¡Nos vemos luego, {{pokemonName}}!"
|
||||
}
|
||||
}
|
||||
|
@ -100,7 +100,7 @@
|
||||
"moveTouchControls": "Controles táctiles",
|
||||
"shopOverlayOpacity": "Opacidad de la fase de compra",
|
||||
"shopCursorTarget": "Cursor de la tienda",
|
||||
"items": "Objetos",
|
||||
"rewards": "Objetos",
|
||||
"reroll": "Actualizar",
|
||||
"shop": "Tienda",
|
||||
"checkTeam": "Ver equipo"
|
||||
|
@ -36,5 +36,6 @@
|
||||
"matBlock": "Tatamigaeshi",
|
||||
"craftyShield": "Vigilance",
|
||||
"tailwind": "Vent Arrière",
|
||||
"happyHour": "Étrennes"
|
||||
}
|
||||
"happyHour": "Étrennes",
|
||||
"safeguard": "Rune Protect"
|
||||
}
|
||||
|
@ -100,7 +100,7 @@
|
||||
"moveTouchControls": "Déplacer les contrôles tactiles",
|
||||
"shopOverlayOpacity": "Opacité boutique",
|
||||
"shopCursorTarget": "Choix après relance",
|
||||
"items": "Obj. gratuits",
|
||||
"rewards": "Obj. gratuits",
|
||||
"reroll": "Relance",
|
||||
"shop": "Boutique",
|
||||
"checkTeam": "Équipe"
|
||||
|
@ -36,5 +36,6 @@
|
||||
"matBlock": "Ribaltappeto",
|
||||
"craftyShield": "Truccodifesa",
|
||||
"tailwind": "Ventoincoda",
|
||||
"happyHour": "Cuccagna"
|
||||
}
|
||||
"happyHour": "Cuccagna",
|
||||
"safeguard": "Salvaguardia"
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
"moveTouchControls": "Move Touch Controls",
|
||||
"shopOverlayOpacity": "Opacità Finestra Negozio",
|
||||
"shopCursorTarget": "Target Cursore Negozio",
|
||||
"items": "Oggetti",
|
||||
"rewards": "Oggetti",
|
||||
"reroll": "Rerolla",
|
||||
"shop": "Negozio",
|
||||
"checkTeam": "Squadra"
|
||||
|
@ -37,7 +37,7 @@
|
||||
"name_female": "ワンパンウーマン"
|
||||
},
|
||||
"HealAchv": {
|
||||
"description": "一つの 技や 特性や 持っているアイテムで\n{{healAmount}}{{HP}}を 一気に 回復する"
|
||||
"description": "一つの 技や 特性や 持たせたアイテムで\n{{HP}}{{healAmount}}を 一気に 回復する"
|
||||
},
|
||||
"250_HEAL": {
|
||||
"name": "回復発見者"
|
||||
@ -52,7 +52,7 @@
|
||||
"name": "ジョーイさん"
|
||||
},
|
||||
"LevelAchv": {
|
||||
"description": "一つの ポケモンを Lv{{level}}まで レベルアップする"
|
||||
"description": "一つの ポケモンを Lv.{{level}}まで 上げる"
|
||||
},
|
||||
"LV_100": {
|
||||
"name": "まだまだだよ"
|
||||
@ -82,7 +82,7 @@
|
||||
"name": "マスターリーグチャンピオン"
|
||||
},
|
||||
"TRANSFER_MAX_STAT_STAGE": {
|
||||
"name": "同力",
|
||||
"name": "連係プレー",
|
||||
"description": "少なくとも 一つの 能力を 最大まで あげて\n他の 手持ちポケモンに バトンタッチする"
|
||||
},
|
||||
"MAX_FRIENDSHIP": {
|
||||
@ -94,7 +94,7 @@
|
||||
"description": "一つの 手持ちポケモンを メガシンカさせる"
|
||||
},
|
||||
"GIGANTAMAX": {
|
||||
"name": "太―くて 堪らない",
|
||||
"name": "太ーくて堪らない",
|
||||
"description": "一つの 手持ちポケモンを キョダイマックスさせる"
|
||||
},
|
||||
"TERASTALLIZE": {
|
||||
@ -106,7 +106,7 @@
|
||||
"description": "一つの 手持ちポケモンを ステラ・テラスタルさせる"
|
||||
},
|
||||
"SPLICE": {
|
||||
"name": "インフィニット・フュジョン",
|
||||
"name": "インフィニット・フュージョン",
|
||||
"description": "遺伝子のくさびで 二つの ポケモンを 吸収合体させる"
|
||||
},
|
||||
"MINI_BLACK_HOLE": {
|
||||
@ -205,7 +205,7 @@
|
||||
"description": "{{type}}タイプの 単一タイプチャレンジを クリアする"
|
||||
},
|
||||
"MONO_NORMAL": {
|
||||
"name": "凡人"
|
||||
"name": "超凡人"
|
||||
},
|
||||
"MONO_FIGHTING": {
|
||||
"name": "八千以上だ!!"
|
||||
@ -223,7 +223,7 @@
|
||||
"name": "タケシの挑戦状"
|
||||
},
|
||||
"MONO_BUG": {
|
||||
"name": "チョウチョウせん者"
|
||||
"name": "チョウチョウ戦者"
|
||||
},
|
||||
"MONO_GHOST": {
|
||||
"name": "貞子ちゃん"
|
||||
|
@ -1 +1,43 @@
|
||||
{}
|
||||
{
|
||||
"activeBattleEffects": "場の効果",
|
||||
"player": "味方",
|
||||
"neutral": "場の全員",
|
||||
"enemy": "相手",
|
||||
|
||||
"sunny": "晴れ",
|
||||
"rain": "雨",
|
||||
"sandstorm": "砂あらし",
|
||||
"hail": "あられ",
|
||||
"snow": "雪",
|
||||
"fog": "きり",
|
||||
"heavyRain": "強い雨",
|
||||
"harshSun": "大日照り",
|
||||
"strongWinds": "乱気流",
|
||||
|
||||
"misty": "ミストフィールド",
|
||||
"electric": "エレキフィールド",
|
||||
"grassy": "グラスフィールド",
|
||||
"psychic": "サイコフィールド",
|
||||
|
||||
"mudSport": "どろあそび",
|
||||
"waterSport": "みずあそび",
|
||||
"spikes": "まきびし",
|
||||
"toxicSpikes": "どくびし",
|
||||
"mist": "しろいきり",
|
||||
"futureSight": "みらいよち",
|
||||
"doomDesire": "はめつのねがい",
|
||||
"wish": "ねがいごと",
|
||||
"stealthRock": "ステルスロック",
|
||||
"stickyWeb": "ねばねばネット",
|
||||
"trickRoom": "トリックルーム",
|
||||
"gravity": "じゅうりょく",
|
||||
"reflect": "リフレクター",
|
||||
"lightScreen": "ひかりのかべ",
|
||||
"auroraVeil": "オーロラベール",
|
||||
"quickGuard": "ファストガード",
|
||||
"wideGuard": "ワイドガード",
|
||||
"matBlock": "たたみがえし",
|
||||
"craftyShield": "トリックガード",
|
||||
"tailwind": "おいかぜ",
|
||||
"happyHour": "ハッピータイム"
|
||||
}
|
||||
|
@ -1 +1,150 @@
|
||||
{}
|
||||
{
|
||||
"music": "Music: ",
|
||||
"missing_entries": "{{name}}",
|
||||
"battle_kanto_champion": "B2W2 Kanto Champion Battle",
|
||||
"battle_johto_champion": "B2W2 Johto Champion Battle",
|
||||
"battle_hoenn_champion_g5": "B2W2 Hoenn Champion Battle",
|
||||
"battle_hoenn_champion_g6": "ORAS Hoenn Champion Battle",
|
||||
"battle_sinnoh_champion": "B2W2 Sinnoh Champion Battle",
|
||||
"battle_champion_alder": "BW Unova Champion Battle",
|
||||
"battle_champion_iris": "B2W2 Unova Champion Battle",
|
||||
"battle_kalos_champion": "XY Kalos Champion Battle",
|
||||
"battle_alola_champion": "USUM Alola Champion Battle",
|
||||
"battle_galar_champion": "SWSH Galar Champion Battle",
|
||||
"battle_champion_geeta": "SV Champion Geeta Battle",
|
||||
"battle_champion_nemona": "SV Champion Nemona Battle",
|
||||
"battle_champion_kieran": "SV Champion Kieran Battle",
|
||||
"battle_hoenn_elite": "ORAS Elite Four Battle",
|
||||
"battle_unova_elite": "BW Elite Four Battle",
|
||||
"battle_kalos_elite": "XY Elite Four Battle",
|
||||
"battle_alola_elite": "SM Elite Four Battle",
|
||||
"battle_galar_elite": "SWSH League Tournament Battle",
|
||||
"battle_paldea_elite": "SV Elite Four Battle",
|
||||
"battle_bb_elite": "SV BB League Elite Four Battle",
|
||||
"battle_final_encounter": "PMD RTDX Rayquaza's Domain",
|
||||
"battle_final": "BW Ghetsis Battle",
|
||||
"battle_kanto_gym": "B2W2 Kanto Gym Battle",
|
||||
"battle_johto_gym": "B2W2 Johto Gym Battle",
|
||||
"battle_hoenn_gym": "B2W2 Hoenn Gym Battle",
|
||||
"battle_sinnoh_gym": "B2W2 Sinnoh Gym Battle",
|
||||
"battle_unova_gym": "BW Unova Gym Battle",
|
||||
"battle_kalos_gym": "XY Kalos Gym Battle",
|
||||
"battle_galar_gym": "SWSH Galar Gym Battle",
|
||||
"battle_paldea_gym": "SV Paldea Gym Battle",
|
||||
"battle_legendary_kanto": "XY Kanto Legendary Battle",
|
||||
"battle_legendary_raikou": "HGSS Raikou Battle",
|
||||
"battle_legendary_entei": "HGSS Entei Battle",
|
||||
"battle_legendary_suicune": "HGSS Suicune Battle",
|
||||
"battle_legendary_lugia": "HGSS Lugia Battle",
|
||||
"battle_legendary_ho_oh": "HGSS Ho-oh Battle",
|
||||
"battle_legendary_regis_g5": "B2W2 Legendary Titan Battle",
|
||||
"battle_legendary_regis_g6": "ORAS Legendary Titan Battle",
|
||||
"battle_legendary_gro_kyo": "ORAS Groudon & Kyogre Battle",
|
||||
"battle_legendary_rayquaza": "ORAS Rayquaza Battle",
|
||||
"battle_legendary_deoxys": "ORAS Deoxys Battle",
|
||||
"battle_legendary_lake_trio": "ORAS Lake Guardians Battle",
|
||||
"battle_legendary_sinnoh": "ORAS Sinnoh Legendary Battle",
|
||||
"battle_legendary_dia_pal": "ORAS Dialga & Palkia Battle",
|
||||
"battle_legendary_origin_forme": "LA Origin Dialga & Palkia Battle",
|
||||
"battle_legendary_giratina": "ORAS Giratina Battle",
|
||||
"battle_legendary_arceus": "HGSS Arceus Battle",
|
||||
"battle_legendary_unova": "BW Unova Legendary Battle",
|
||||
"battle_legendary_kyurem": "BW Kyurem Battle",
|
||||
"battle_legendary_res_zek": "BW Reshiram & Zekrom Battle",
|
||||
"battle_legendary_xern_yvel": "XY Xerneas & Yveltal Battle",
|
||||
"battle_legendary_tapu": "SM Tapu Battle",
|
||||
"battle_legendary_sol_lun": "SM Solgaleo & Lunala Battle",
|
||||
"battle_legendary_ub": "SM Ultra Beast Battle",
|
||||
"battle_legendary_dusk_dawn": "USUM Dusk Mane & Dawn Wings Necrozma Battle",
|
||||
"battle_legendary_ultra_nec": "USUM Ultra Necrozma Battle",
|
||||
"battle_legendary_zac_zam": "SWSH Zacian & Zamazenta Battle",
|
||||
"battle_legendary_glas_spec": "SWSH Glastrier & Spectrier Battle",
|
||||
"battle_legendary_calyrex": "SWSH Calyrex Battle",
|
||||
"battle_legendary_riders": "SWSH Ice & Shadow Rider Calyrex Battle",
|
||||
"battle_legendary_birds_galar": "SWSH Galarian Legendary Birds Battle",
|
||||
"battle_legendary_ruinous": "SV Treasures of Ruin Battle",
|
||||
"battle_legendary_kor_mir": "SV Depths of Area Zero Battle",
|
||||
"battle_legendary_loyal_three": "SV Loyal Three Battle",
|
||||
"battle_legendary_ogerpon": "SV Ogerpon Battle",
|
||||
"battle_legendary_terapagos": "SV Terapagos Battle",
|
||||
"battle_legendary_pecharunt": "SV Pecharunt Battle",
|
||||
"battle_rival": "BW Rival Battle",
|
||||
"battle_rival_2": "BW N Battle",
|
||||
"battle_rival_3": "BW Final N Battle",
|
||||
"battle_trainer": "BW Trainer Battle",
|
||||
"battle_wild": "BW Wild Battle",
|
||||
"battle_wild_strong": "BW Strong Wild Battle",
|
||||
"end_summit": "PMD RTDX Sky Tower Summit",
|
||||
"battle_rocket_grunt": "HGSS Team Rocket Battle",
|
||||
"battle_aqua_magma_grunt": "ORAS Team Aqua & Magma Battle",
|
||||
"battle_galactic_grunt": "BDSP Team Galactic Battle",
|
||||
"battle_plasma_grunt": "BW Team Plasma Battle",
|
||||
"battle_flare_grunt": "XY Team Flare Battle",
|
||||
"battle_aether_grunt": "SM Aether Foundation Battle",
|
||||
"battle_skull_grunt": "SM Team Skull Battle",
|
||||
"battle_macro_grunt": "SWSH Trainer Battle",
|
||||
"battle_galactic_admin": "BDSP Team Galactic Admin Battle",
|
||||
"battle_skull_admin": "SM Team Skull Admin Battle",
|
||||
"battle_oleana": "SWSH Oleana Battle",
|
||||
"battle_rocket_boss": "USUM Giovanni Battle",
|
||||
"battle_aqua_magma_boss": "ORAS Archie & Maxie Battle",
|
||||
"battle_galactic_boss": "BDSP Cyrus Battle",
|
||||
"battle_plasma_boss": "B2W2 Ghetsis Battle",
|
||||
"battle_flare_boss": "XY Lysandre Battle",
|
||||
"battle_aether_boss": "SM Lusamine Battle",
|
||||
"battle_skull_boss": "SM Guzma Battle",
|
||||
"battle_macro_boss": "SWSH Rose Battle",
|
||||
|
||||
"abyss": "PMD EoS Dark Crater",
|
||||
"badlands": "PMD EoS Barren Valley",
|
||||
"beach": "PMD EoS Drenched Bluff",
|
||||
"cave": "PMD EoS Sky Peak Cave",
|
||||
"construction_site": "PMD EoS Boulder Quarry",
|
||||
"desert": "PMD EoS Northern Desert",
|
||||
"dojo": "PMD EoS Marowak Dojo",
|
||||
"end": "PMD RTDX Sky Tower",
|
||||
"factory": "PMD EoS Concealed Ruins",
|
||||
"fairy_cave": "PMD EoS Star Cave",
|
||||
"forest": "PMD EoS Dusk Forest",
|
||||
"grass": "PMD EoS Apple Woods",
|
||||
"graveyard": "PMD EoS Mystifying Forest",
|
||||
"ice_cave": "PMD EoS Vast Ice Mountain",
|
||||
"island": "PMD EoS Craggy Coast",
|
||||
"jungle": "Lmz - Jungle",
|
||||
"laboratory": "Firel - Laboratory",
|
||||
"lake": "PMD EoS Crystal Cave",
|
||||
"meadow": "PMD EoS Sky Peak Forest",
|
||||
"metropolis": "Firel - Metropolis",
|
||||
"mountain": "PMD EoS Mt. Horn",
|
||||
"plains": "PMD EoS Sky Peak Prairie",
|
||||
"power_plant": "PMD EoS Far Amp Plains",
|
||||
"ruins": "PMD EoS Deep Sealed Ruin",
|
||||
"sea": "Andr06 - Marine Mystique",
|
||||
"seabed": "Firel - Seabed",
|
||||
"slum": "Andr06 - Sneaky Snom",
|
||||
"snowy_forest": "PMD EoS Sky Peak Snowfield",
|
||||
"space": "Firel - Aether",
|
||||
"swamp": "PMD EoS Surrounded Sea",
|
||||
"tall_grass": "PMD EoS Foggy Forest",
|
||||
"temple": "PMD EoS Aegis Cave",
|
||||
"town": "PMD EoS Random Dungeon Theme 3",
|
||||
"volcano": "PMD EoS Steam Cave",
|
||||
"wasteland": "PMD EoS Hidden Highland",
|
||||
"encounter_ace_trainer": "BW Trainers' Eyes Meet (Ace Trainer)",
|
||||
"encounter_backpacker": "BW Trainers' Eyes Meet (Backpacker)",
|
||||
"encounter_clerk": "BW Trainers' Eyes Meet (Clerk)",
|
||||
"encounter_cyclist": "BW Trainers' Eyes Meet (Cyclist)",
|
||||
"encounter_lass": "BW Trainers' Eyes Meet (Lass)",
|
||||
"encounter_parasol_lady": "BW Trainers' Eyes Meet (Parasol Lady)",
|
||||
"encounter_pokefan": "BW Trainers' Eyes Meet (Poke Fan)",
|
||||
"encounter_psychic": "BW Trainers' Eyes Meet (Psychic)",
|
||||
"encounter_rich": "BW Trainers' Eyes Meet (Gentleman)",
|
||||
"encounter_rival": "BW Cheren",
|
||||
"encounter_roughneck": "BW Trainers' Eyes Meet (Roughneck)",
|
||||
"encounter_scientist": "BW Trainers' Eyes Meet (Scientist)",
|
||||
"encounter_twins": "BW Trainers' Eyes Meet (Twins)",
|
||||
"encounter_youngster": "BW Trainers' Eyes Meet (Youngster)",
|
||||
"heal": "BW Pokémon Heal",
|
||||
"menu": "PMD EoS Welcome to the World of Pokémon!",
|
||||
"title": "PMD EoS Top Menu Theme"
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"title": "チャレンジを 設定",
|
||||
"title": "チャレンジの設定",
|
||||
"illegalEvolution": "{{pokemon}}は このチャレンジで\n対象外の ポケモンに なってしまった!",
|
||||
"singleGeneration": {
|
||||
"name": "単一世代",
|
||||
|
@ -1 +1,8 @@
|
||||
{}
|
||||
{
|
||||
"start": "スタート",
|
||||
"luckIndicator": "運:",
|
||||
"shinyOnHover": "色違い",
|
||||
"commonShiny": "ふつう",
|
||||
"rareShiny": "レア",
|
||||
"epicShiny": "超レア"
|
||||
}
|
||||
|
@ -1 +1,84 @@
|
||||
{}
|
||||
{
|
||||
"blue_red_double": {
|
||||
"encounter": {
|
||||
"1": "Blue: Hey Red, let's show them what we're made of!\n$Red: ...\n$Blue: This is Pallet Town Power!"
|
||||
},
|
||||
"victory": {
|
||||
"1": "Blue: That was a great battle!\n$Red: ..."
|
||||
}
|
||||
},
|
||||
"red_blue_double": {
|
||||
"encounter": {
|
||||
"1": "Red: ...!\n$Blue: He never talks much.\n$Blue: But dont let that fool you! He is a champ after all!"
|
||||
},
|
||||
"victory": {
|
||||
"1": "Red: ...!\n$Blue: Next time we will beat you!"
|
||||
}
|
||||
},
|
||||
"tate_liza_double": {
|
||||
"encounter": {
|
||||
"1": "Tate: Are you surprised?\n$Liza: We are two gym leaders at once!\n$Tate: We are twins!\n$Liza: We dont need to talk to understand each other!\n$Tate: Twice the power...\n$Liza: Can you handle it?"
|
||||
},
|
||||
"victory": {
|
||||
"1": "Tate: What? Our combination was perfect!\n$Liza: Looks like we need to train more..."
|
||||
}
|
||||
},
|
||||
"liza_tate_double": {
|
||||
"encounter": {
|
||||
"1": "Liza: Hihihi... Are you surprised?\n$Tate: Yes, we are really two gym leaders at once!\n$Liza: This is my twin brother Tate!\n$Tate: And this is my twin sister Liza!\n$Liza: Don't you think we are a perfect combination?"
|
||||
},
|
||||
"victory": {
|
||||
"1": "Liza: Are we...\n$Tate: ...not as strong as we thought?"
|
||||
}
|
||||
},
|
||||
"wallace_steven_double": {
|
||||
"encounter": {
|
||||
"1": "Steven: Wallace, let's show them the power of the champions!\n$Wallace: We will show you the power of Hoenn!\n$Steven: Let's go!"
|
||||
},
|
||||
"victory": {
|
||||
"1": "Steven: That was a great battle!\n$Wallace: We will win next time!"
|
||||
}
|
||||
},
|
||||
"steven_wallace_double": {
|
||||
"encounter": {
|
||||
"1": "Steven: Do you have any rare Pokémon?\n$Wallace: Steven... We are here for a battle, not to show off our Pokémon.\n$Steven: Oh... I see... Let's go then!"
|
||||
},
|
||||
"victory": {
|
||||
"1": "Steven: Now that we are done with the battle, let's show off our Pokémon!\n$Wallace: Steven..."
|
||||
}
|
||||
},
|
||||
"alder_iris_double": {
|
||||
"encounter": {
|
||||
"1": "Alder: We are the strongest trainers in Unova!\n$Iris: Fights against strong trainers are the best!"
|
||||
},
|
||||
"victory": {
|
||||
"1": "Alder: Wow! You are super strong!\n$Iris: We will win next time!"
|
||||
}
|
||||
},
|
||||
"iris_alder_double": {
|
||||
"encounter": {
|
||||
"1": "Iris: Welcome Challenger! I am THE Unova Champion!\n$Alder: Iris, aren't you a bit too excited?",
|
||||
"1_female": "Iris: Welcome Challenger! I am THE Unova Champion!\n$Alder: Iris, aren't you a bit too excited?"
|
||||
},
|
||||
"victory": {
|
||||
"1": "Iris: A loss like this is not easy to take...\n$Alder: But we will only get stronger with every loss!"
|
||||
}
|
||||
},
|
||||
"piers_marnie_double": {
|
||||
"encounter": {
|
||||
"1": "Marnie: Brother, let's show them the power of Spikemuth!\n$Piers: We bring darkness!"
|
||||
},
|
||||
"victory": {
|
||||
"1": "Marnie: You brought light to our darkness!\n$Piers: Its too bright..."
|
||||
}
|
||||
},
|
||||
"marnie_piers_double": {
|
||||
"encounter": {
|
||||
"1": "Piers: Ready for a concert?\n$Marnie: Brother... They are here to fight, not to sing...",
|
||||
"1_female": "Piers: Ready for a concert?\n$Marnie: Brother... They are here to fight, not to sing..."
|
||||
},
|
||||
"victory": {
|
||||
"1": "Piers: Now that was a great concert!\n$Marnie: Brother..."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1 +1,10 @@
|
||||
{}
|
||||
{
|
||||
"encounter": "It appears the time has finally come once again.\nYou know why you have come here, do you not?\n$You were drawn here, because you have been here before.\nCountless times.\n$Though, perhaps it can be counted.\nTo be precise, this is in fact your {{cycleCount}} cycle.\n$Each cycle your mind reverts to its former state.\nEven so, somehow, remnants of your former selves remain.\n$Until now you have yet to succeed, but I sense a different presence in you this time.\n\n$You are the only one here, though it is as if there is… another.\n$Will you finally prove a formidable challenge to me?\nThe challenge I have longed after for millennia?\n$We begin.",
|
||||
"encounter_female": "It appears the time has finally come once again.\nYou know why you have come here, do you not?\n$You were drawn here, because you have been here before.\nCountless times.\n$Though, perhaps it can be counted.\nTo be precise, this is in fact your {{cycleCount}} cycle.\n$Each cycle your mind reverts to its former state.\nEven so, somehow, remnants of your former selves remain.\n$Until now you have yet to succeed, but I sense a different presence in you this time.\n\n$You are the only one here, though it is as if there is… another.\n$Will you finally prove a formidable challenge to me?\nThe challenge I have longed after for millennia?\n$We begin.",
|
||||
"firstStageWin": "I see. The presence I felt was indeed real.\nIt appears I no longer need to hold back.\n$Do not disappoint me.",
|
||||
"secondStageWin": "…Magnificent.",
|
||||
"key_ordinal_one": "st",
|
||||
"key_ordinal_two": "nd",
|
||||
"key_ordinal_few": "rd",
|
||||
"key_ordinal_other": "th"
|
||||
}
|
||||
|
@ -1 +1,6 @@
|
||||
{}
|
||||
{
|
||||
"ending": "@c{shock}You're back?@d{32} Does that mean…@d{96} you won?!\n@c{smile_ehalf}I should have known you had it in you.\n$@c{smile_eclosed}Of course… I always had that feeling.\n@c{smile}It's over now, right? You ended the loop.\n$@c{smile_ehalf}You fulfilled your dream too, didn't you?\nYou didn't lose even once.\n$I'll be the only one to remember what you did.\n@c{angry_mopen}I'll try not to forget!\n$@c{smile_wave_wink}Just kidding!@d{64} @c{smile}I'd never forget.@d{32}\nYour legend will live on in our hearts.\n$@c{smile_wave}Anyway,@d{64} it's getting late…@d{96} I think?\nIt's hard to tell in this place.\n$Let's go home. @c{smile_wave_wink}Maybe tomorrow, we can have another battle, for old time's sake?",
|
||||
"ending_female": "@c{smile}Oh? You won?@d{96} @c{smile_eclosed}I guess I should've known.\nBut, you're back now.\n$@c{smile}It's over.@d{64} You ended the loop.\n$@c{serious_smile_fists}You fulfilled your dream too, didn't you?\nYou didn't lose even once.\n$@c{neutral}I'm the only one who'll remember what you did.@d{96}\nI guess that's okay, isn't it?\n$@c{serious_smile_fists}Your legend will always live on in our hearts.\n$@c{smile_eclosed}Anyway, I've had about enough of this place, haven't you? Let's head home.\n$@c{serious_smile_fists}Maybe when we get back, we can have another battle?\nIf you're up to it.",
|
||||
"ending_endless": "Congratulations on reaching the current end!\nMore content is coming soon.",
|
||||
"ending_name": "Devs"
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"pp": "PP",
|
||||
"power": "いりょく",
|
||||
"accuracy": "めいちゅう",
|
||||
"abilityFlyInText": " {{pokemonName}}の {{passive}}{{abilityName}}",
|
||||
"passive": "Passive "
|
||||
}
|
||||
"power": "威力",
|
||||
"accuracy": "命中",
|
||||
"abilityFlyInText": " {{pokemonName}}の\n{{passive}}:{{abilityName}}",
|
||||
"passive": "パッシブ "
|
||||
}
|
||||
|
@ -32,7 +32,7 @@
|
||||
"noPokerus": "ポケルス - なし",
|
||||
"sortByNumber": "No.",
|
||||
"sortByCost": "ポイント",
|
||||
"sortByCandies": "飴の数",
|
||||
"sortByCandies": "アメの数",
|
||||
"sortByIVs": "個体値",
|
||||
"sortByName": "名前"
|
||||
}
|
||||
}
|
||||
|
@ -12,26 +12,26 @@
|
||||
"dailyRunAttempts": "デイリーラン",
|
||||
"dailyRunWins": "デイリーラン勝利",
|
||||
"endlessRuns": "エンドレスラン",
|
||||
"highestWaveEndless": "エンドレス最高波",
|
||||
"highestWaveEndless": "エンドレス最高ラウンド",
|
||||
"highestMoney": "最大貯金",
|
||||
"highestDamage": "最大ダメージ",
|
||||
"highestHPHealed": "最大HP回復",
|
||||
"pokemonEncountered": "遭遇したポケモン",
|
||||
"pokemonDefeated": "倒したポケモン",
|
||||
"pokemonCaught": "捕まえたポケモン",
|
||||
"eggsHatched": "孵化したタマゴ",
|
||||
"eggsHatched": "ふかしたタマゴ",
|
||||
"subLegendsSeen": "見つけた順伝説ポケモン",
|
||||
"subLegendsCaught": "捕まえた準伝説ポケモン",
|
||||
"subLegendsHatched": "孵化した準伝説ポケモン",
|
||||
"subLegendsHatched": "ふかした準伝説ポケモン",
|
||||
"legendsSeen": "見つけた伝説ポケモン",
|
||||
"legendsCaught": "捕まえた伝説ポケモン",
|
||||
"legendsHatched": "孵化した伝説ポケモン",
|
||||
"legendsHatched": "ふかした伝説ポケモン",
|
||||
"mythicalsSeen": "見つけた幻ポケモン",
|
||||
"mythicalsCaught": "捕まえた幻ポケモン",
|
||||
"mythicalsHatched": "孵化した幻ポケモン",
|
||||
"mythicalsHatched": "ふかした幻ポケモン",
|
||||
"shiniesSeen": "見つけた色違いポケモン",
|
||||
"shiniesCaught": "捕まえた色違いポケモン",
|
||||
"shiniesHatched": "孵化した色違いポケモン",
|
||||
"shiniesHatched": "ふかした色違いポケモン",
|
||||
"pokemonFused": "吸収合体したポケモン",
|
||||
"trainersDefeated": "倒したトレーナー",
|
||||
"eggsPulled": "引いたタマゴ",
|
||||
|
@ -1,8 +1,8 @@
|
||||
{
|
||||
"Erratic": "60まんタイプ",
|
||||
"Fast": "80まんタイプ",
|
||||
"Medium_Fast": "100まんタイプ",
|
||||
"Medium_Slow": "105まんタイプ",
|
||||
"Slow": "125まんタイプ",
|
||||
"Fluctuating": "164まんタイプ"
|
||||
}
|
||||
"Erratic": "60万タイプ",
|
||||
"Fast": "80万タイプ",
|
||||
"Medium_Fast": "100万タイプ",
|
||||
"Medium_Slow": "105万タイプ",
|
||||
"Slow": "125万タイプ",
|
||||
"Fluctuating": "164万タイプ"
|
||||
}
|
||||
|
@ -24,6 +24,6 @@
|
||||
"linkGoogle": "Google連携",
|
||||
"unlinkGoogle": "Google連携解除",
|
||||
"cancel": "キャンセル",
|
||||
"losingProgressionWarning": "戦闘開始からの データが 保存されません。\nよろしいですか?",
|
||||
"noEggs": "現在は タマゴを 孵化していません!"
|
||||
"losingProgressionWarning": "戦闘開始からの データが セーブされません。\nよろしいですか?",
|
||||
"noEggs": "現在は タマゴを ふかしていません!"
|
||||
}
|
||||
|
@ -353,7 +353,7 @@
|
||||
"description": "やせいのポケモンがかくれとくせいをもつかくりつをおおきくふやす"
|
||||
},
|
||||
"IV_SCANNER": {
|
||||
"name": "こたいち たんちき",
|
||||
"name": "こたいちスキャナー",
|
||||
"description": "やせいのポケモンのこたいちをスキャンできる。スタックごとに2つのこたいちがあきらかになる。もっともたかいこたいちがさいしょにひょうじされる"
|
||||
},
|
||||
"DNA_SPLICERS": {
|
||||
|
@ -1,12 +1,12 @@
|
||||
{
|
||||
"surviveDamageApply": "{{pokemonNameWithAffix}}は\n{{typeName}}で もちこたえた!",
|
||||
"turnHealApply": "{{pokemonNameWithAffix}}は\n{{typeName}}で 少し 回復!",
|
||||
"hitHealApply": "{{pokemonNameWithAffix}}は\n{{typeName}}で 少し 回復!",
|
||||
"turnHealApply": "{{pokemonNameWithAffix}}は\n{{typeName}}で 少し 体力を 回復した!",
|
||||
"hitHealApply": "{{pokemonNameWithAffix}}は\n{{typeName}}で 少し 体力を 回復した!",
|
||||
"pokemonInstantReviveApply": "{{pokemonNameWithAffix}}は\n{{typeName}}で 復活した!",
|
||||
"resetNegativeStatStageApply": "{{pokemonNameWithAffix}}は {{typeName}}で\n下がった能力が 元に戻った!",
|
||||
"moneyInterestApply": "{{typeName}}から {{moneyAmount}}円 取得した!",
|
||||
"turnHeldItemTransferApply": "{{pokemonName}}の {{typeName}}が\n{{pokemonNameWithAffix}}の {{itemName}}を 吸い取った!",
|
||||
"contactHeldItemTransferApply": "{{pokemonName}}の {{typeName}}が\n{{pokemonNameWithAffix}}の {{itemName}}を うばい取った!",
|
||||
"turnHeldItemTransferApply": "{{pokemonName}}の {{typeName}}が\n{{pokemonNameWithAffix}}の {{itemName}}を 吸い取った!",
|
||||
"contactHeldItemTransferApply": "{{pokemonName}}の {{typeName}}が\n{{pokemonNameWithAffix}}の {{itemName}}を 奪い取った!",
|
||||
"enemyTurnHealApply": "{{pokemonNameWithAffix}}は\n体力を 回復!",
|
||||
"bypassSpeedChanceApply": "{{pokemonName}}は {{itemName}}で\n行動が はやくなった!"
|
||||
}
|
||||
}
|
||||
|
@ -1,64 +1,69 @@
|
||||
{
|
||||
"hitWithRecoil": "{{pokemonName}}は\nはんどうによる ダメージを うけた!",
|
||||
"cutHpPowerUpMove": "{{pokemonName}}は\nたいりょくを けずって パワーぜんかい!",
|
||||
"absorbedElectricity": "{{pokemonName}}は\n でんきを きゅうしゅうした!",
|
||||
"switchedStatChanges": "{{pokemonName}}は あいてと じぶんの\nのうりょくへんかを いれかえた!",
|
||||
"sharedGuard": "{{pokemonName}}は\nおたがいのガードを シェアした!",
|
||||
"sharedPower": "{{pokemonName}}は\nおたがいのパワーを シェアした!",
|
||||
"goingAllOutForAttack": "{{pokemonName}}は\nほんきを だした!",
|
||||
"regainedHealth": "{{pokemonName}}は\nたいりょくを かいふくした!",
|
||||
"keptGoingAndCrashed": "いきおいあまって {{pokemonName}}は\nじめんに ぶつかった!",
|
||||
"fled": "{{pokemonName}}は にげだした!",
|
||||
"cannotBeSwitchedOut": "{{pokemonName}}を\nもどすことが できない!",
|
||||
"swappedAbilitiesWithTarget": "{{pokemonName}}は\nおたがいの とくせいを いれかえた!",
|
||||
"coinsScatteredEverywhere": "こばんが あたりに ちらばった!",
|
||||
"hitWithRecoil": "{{pokemonName}}は\n反動による ダメージを 受けた!",
|
||||
"cutHpPowerUpMove": "{{pokemonName}}は\n体力を 削って 技の 威力を 上がった!",
|
||||
"absorbedElectricity": "{{pokemonName}}は\n 電気を 吸収した!",
|
||||
"switchedStatChanges": "{{pokemonName}}は 相手と 自分の\n能力変化を 入れ替えた!",
|
||||
"switchedTwoStatChanges": "{{pokemonName}}は 相手と 自分の {{firstStat}}と\n{{secondStat}}の 能力変化を 入れ替えた!",
|
||||
"switchedStat": "{{pokemonName}}は 相手と {{stat}}を 入れ替えた!",
|
||||
"sharedGuard": "{{pokemonName}}は\nお互いのガードを シェアした!",
|
||||
"sharedPower": "{{pokemonName}}は\nお互いのパワーを シェアした!",
|
||||
"goingAllOutForAttack": "{{pokemonName}}は\n本気を 出した!",
|
||||
"regainedHealth": "{{pokemonName}}は\n体力を 回復した!",
|
||||
"keptGoingAndCrashed": "勢い余って {{pokemonName}}は\n地面に ぶつかった!",
|
||||
"fled": "{{pokemonName}}は 逃げ出した!",
|
||||
"cannotBeSwitchedOut": "{{pokemonName}}を\n戻すことが できない!",
|
||||
"swappedAbilitiesWithTarget": "{{pokemonName}}は\nお互いの 特性を 入れ替えた!",
|
||||
"coinsScatteredEverywhere": "小判が 辺りに 散らばった!",
|
||||
"attackedByItem": "{{pokemonName}}に\n{{itemName}}が おそいかかる!",
|
||||
"whippedUpAWhirlwind": "{{pokemonName}}の まわりで\nくうきが うずをまく!",
|
||||
"flewUpHigh": "{{pokemonName}}は\nそらたかく とびあがった!",
|
||||
"tookInSunlight": "{{pokemonName}}は\nひかりを きゅうしゅうした!",
|
||||
"dugAHole": "{{pokemonName}}は\nじめんに もぐった!",
|
||||
"loweredItsHead": "{{pokemonName}}は\nくびを ひっこめた!",
|
||||
"isGlowing": "{{pokemonName}}を\nはげしいひかりが つつむ!",
|
||||
"bellChimed": "すずのおとが ひびきわたった!",
|
||||
"foresawAnAttack": "{{pokemonName}}は\nみらいに こうげきを よちした!",
|
||||
"hidUnderwater": "{{pokemonName}}は\nすいちゅうに みをひそめた!",
|
||||
"soothingAromaWaftedThroughArea": "ここちよい かおりが ひろがった!",
|
||||
"sprangUp": "{{pokemonName}}は\nたかく とびはねた!",
|
||||
"choseDoomDesireAsDestiny": "{{pokemonName}}は\nはめつのねがいを みらいに たくした!",
|
||||
"vanishedInstantly": "{{pokemonName}}の すがたが\nいっしゅんにして きえた!",
|
||||
"tookTargetIntoSky": "{{pokemonName}}は {{targetName}}を\nじょうくうに つれさった!",
|
||||
"becameCloakedInFreezingLight": "{{pokemonName}}は\nつめたいひかりに つつまれた!",
|
||||
"becameCloakedInFreezingAir": "{{pokemonName}}は\nこごえるくうきに つつまれた!",
|
||||
"isChargingPower": "{{pokemonName}}は\nパワーを ためこんでいる!",
|
||||
"burnedItselfOut": "{{pokemonName}}の ほのうは\nもえつきた!",
|
||||
"startedHeatingUpBeak": "{{pokemonName}}は\nクチバシを かねつしはじめた!",
|
||||
"whippedUpAWhirlwind": "{{pokemonName}}の 周りで\n空気が 渦を巻く!",
|
||||
"flewUpHigh": "{{pokemonName}}は\n空高く 飛び上がった!",
|
||||
"tookInSunlight": "{{pokemonName}}は\n光を 吸収した!",
|
||||
"dugAHole": "{{pokemonName}}は\n地面に 潜った!",
|
||||
"loweredItsHead": "{{pokemonName}}は\n首を 引っ込めた!",
|
||||
"isGlowing": "{{pokemonName}}を\n激しい光が 包む!",
|
||||
"bellChimed": "鈴の音が 響き渡った!",
|
||||
"foresawAnAttack": "{{pokemonName}}は\n未来に 攻撃を 予知した!",
|
||||
"isTighteningFocus": "{{pokemonName}}は\n集中力を 高めている!",
|
||||
"hidUnderwater": "{{pokemonName}}は\n水中に 身を潜めた!",
|
||||
"soothingAromaWaftedThroughArea": "心地よい 香りが 広がった!",
|
||||
"sprangUp": "{{pokemonName}}は\n高く 飛び跳ねた!",
|
||||
"choseDoomDesireAsDestiny": "{{pokemonName}}は\nはめつのねがいを 未来に 託した!",
|
||||
"vanishedInstantly": "{{pokemonName}}の 姿が\n一瞬にして 消えた!",
|
||||
"tookTargetIntoSky": "{{pokemonName}}は {{targetName}}を\n上空に 連れ去った!",
|
||||
"becameCloakedInFreezingLight": "{{pokemonName}}は\n冷たい光に 包まれた!",
|
||||
"becameCloakedInFreezingAir": "{{pokemonName}}は\n凍える空気に 包まれた!",
|
||||
"isChargingPower": "{{pokemonName}}は\nパワーを 溜め込んでいる!",
|
||||
"burnedItselfOut": "{{pokemonName}}の 炎は 燃え尽きた!",
|
||||
"startedHeatingUpBeak": "{{pokemonName}}は\nクチバシを 加熱し始めた!",
|
||||
"setUpShellTrap": "{{pokemonName}}は\nトラップシェルを 仕掛けた!",
|
||||
"isOverflowingWithSpacePower": "{{pokemonName}}に\nうちゅうの ちからが あふれだす!",
|
||||
"usedUpAllElectricity": "{{pokemonName}}は\nでんきを つかいきった!",
|
||||
"stoleItem": "{{pokemonName}}は\n{{targetName}}の {{itemName}}を ぬすんだ!",
|
||||
"incineratedItem": "{{pokemonName}}は\n{{targetName}}の {{itemName}}を もやした!",
|
||||
"knockedOffItem": "{{pokemonName}}は\n{{targetName}}の {{itemName}}を はたきおとした!",
|
||||
"tookMoveAttack": "{{pokemonName}}は\n{{moveName}}の こうげきを うけた!",
|
||||
"cutOwnHpAndMaximizedStat": "{{pokemonName}}は\nたいりょくを けずって {{statName}}ぜんかい!",
|
||||
"copiedStatChanges": "{{pokemonName}}は {{targetName}}の\nのうりょくへんかを コピーした!",
|
||||
"isOverflowingWithSpacePower": "{{pokemonName}}に\n宇宙の 力が 溢れ出す!",
|
||||
"usedUpAllElectricity": "{{pokemonName}}は\n電気を 使い切った!",
|
||||
"stoleItem": "{{pokemonName}}は\n{{targetName}}の {{itemName}}を 盗んだ!",
|
||||
"incineratedItem": "{{pokemonName}}は\n{{targetName}}の {{itemName}}を 燃やした!",
|
||||
"knockedOffItem": "{{pokemonName}}は\n{{targetName}}の {{itemName}}を はたき落とした!",
|
||||
"tookMoveAttack": "{{pokemonName}}は\n{{moveName}}の 攻撃を 受けた!",
|
||||
"cutOwnHpAndMaximizedStat": "{{pokemonName}}は\n体力を 削って {{statName}}全開!",
|
||||
"copiedStatChanges": "{{pokemonName}}は {{targetName}}の\n能力変化を コピーした!",
|
||||
"magnitudeMessage": "マグニチュード{{magnitude}}!",
|
||||
"tookAimAtTarget": "{{pokemonName}}は {{targetName}}に\nねらいを さだめた!",
|
||||
"tookAimAtTarget": "{{pokemonName}}は {{targetName}}に\n狙いを 定めた!",
|
||||
"transformedIntoType": "{{pokemonName}}は\n{{typeName}}タイプに なった!",
|
||||
"copiedMove": "{{pokemonName}}は\n{{moveName}}を コピーした!",
|
||||
"sketchedMove": "{{pokemonName}}は\n{{moveName}}を スケッチした!",
|
||||
"acquiredAbility": "{{pokemonName}}の とくせいが\n{{abilityName}}に なった!",
|
||||
"acquiredAbility": "{{pokemonName}}の 特性が\n{{abilityName}}に なった!",
|
||||
"copiedTargetAbility": "{{pokemonName}}は\n{{targetName}}の {{abilityName}}を コピーした!",
|
||||
"transformedIntoTarget": "{{pokemonName}}は\n{{targetName}}に へんしんした!",
|
||||
"tryingToTakeFoeDown": "{{pokemonName}}は あいてを\nみちづれに しようとしている!",
|
||||
"addType": "{{pokemonName}}に\n{{typeName}}タイプが ついかされた!",
|
||||
"cannotUseMove": "{{pokemonName}}は\n{{moveName}}を つかえなかった!",
|
||||
"healHp": "{{pokemonName}}の\nたいりょくが かいふくした!",
|
||||
"sacrificialFullRestore": "{{pokemonName}}の\nねがいごとが かなった!",
|
||||
"invertStats": "{{pokemonName}}の\nのうりょくへんかが ぎゃくてんした!",
|
||||
"resetStats": "{{pokemonName}}の\nのうりょくへんかが もとにもどった!",
|
||||
"faintCountdown": "{{pokemonName}}は\n{{turnCount}}ターンごに ほろびてしまう!",
|
||||
"transformedIntoTarget": "{{pokemonName}}は\n{{targetName}}に 変身した!",
|
||||
"tryingToTakeFoeDown": "{{pokemonName}}は 相手を\nみちづれに しようとしている!",
|
||||
"addType": "{{pokemonName}}に\n{{typeName}}タイプが 追加された!",
|
||||
"cannotUseMove": "{{pokemonName}}は\n{{moveName}}を 使えなかった!",
|
||||
"healHp": "{{pokemonName}}の\n体力が 回復した!",
|
||||
"sacrificialFullRestore": "{{pokemonName}}の\nいやしのねがいが 叶った!",
|
||||
"invertStats": "{{pokemonName}}は\n能力変化が ひっくり返った!",
|
||||
"resetStats": "{{pokemonName}}の\n能力変化が 元に戻った!",
|
||||
"statEliminated": "全ての 能力変化が 元に戻った!",
|
||||
"faintCountdown": "{{pokemonName}}は\n{{turnCount}}ターン後に 滅びてしまう!",
|
||||
"copyType": "{{pokemonName}}は {{targetPokemonName}}と\n同じタイプに なった!",
|
||||
"suppressAbilities": "{{pokemonName}}の とくせいが きかなくなった!",
|
||||
"suppressAbilities": "{{pokemonName}}の 特性が 効かなくなった!",
|
||||
"revivalBlessing": "{{pokemonName}}は\n復活して 戦えるようになった!",
|
||||
"swapArenaTags": "{{pokemonName}}は\nおたがいの ばのこうかを いれかえた!"
|
||||
"swapArenaTags": "{{pokemonName}}は\nお互いの 場の 効果を 入れ替えた!",
|
||||
"exposedMove": "{{pokemonName}}は {{targetPokemonName}}の\n正体を 見破った!"
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
{
|
||||
"SEND_OUT": "いれかえる",
|
||||
"SUMMARY": "つよさをみる",
|
||||
"SEND_OUT": "入れ替える",
|
||||
"SUMMARY": "強さを見る",
|
||||
"CANCEL": "やめる",
|
||||
"RELEASE": "にがす",
|
||||
"APPLY": "つかう",
|
||||
"TEACH": "おしえる"
|
||||
}
|
||||
"RELEASE": "逃がす",
|
||||
"APPLY": "使う",
|
||||
"TEACH": "教える"
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"moveset": "わざ",
|
||||
"gender": "せいべつ:",
|
||||
"ability": "とくせい:",
|
||||
"nature": "せいかく:",
|
||||
"form": "すがた:"
|
||||
}
|
||||
"moveset": "技",
|
||||
"gender": "性別:",
|
||||
"ability": "特性:",
|
||||
"nature": "性格:",
|
||||
"form": "姿:"
|
||||
}
|
||||
|
@ -1 +1,44 @@
|
||||
{}
|
||||
{
|
||||
"pokemonInfo": "ポケモン情報",
|
||||
"status": "ステータス",
|
||||
"powerAccuracyCategory": "威力\n命中\n分類",
|
||||
"type": "タイプ",
|
||||
"unknownTrainer": "???",
|
||||
"ot": "親",
|
||||
"nature": "性格",
|
||||
"expPoints": "経験値",
|
||||
"nextLv": "次のレベルまで",
|
||||
"cancel": "キャンセル",
|
||||
"memoString": "{{natureFragment}}な性格。\n{{metFragment}}",
|
||||
"metFragment": {
|
||||
"normal": "{{biome}}で\nLv.{{level}}の時に出会った。",
|
||||
"apparently": "{{biome}}で\nLv.{{level}}の時に出会ったようだ。"
|
||||
},
|
||||
"natureFragment": {
|
||||
"Hardy": "{{nature}}",
|
||||
"Lonely": "{{nature}}",
|
||||
"Brave": "{{nature}}",
|
||||
"Adamant": "{{nature}}",
|
||||
"Naughty": "{{nature}}",
|
||||
"Bold": "{{nature}}",
|
||||
"Docile": "{{nature}}",
|
||||
"Relaxed": "{{nature}}",
|
||||
"Impish": "{{nature}}",
|
||||
"Lax": "{{nature}}",
|
||||
"Timid": "{{nature}}",
|
||||
"Hasty": "{{nature}}",
|
||||
"Serious": "{{nature}}",
|
||||
"Jolly": "{{nature}}",
|
||||
"Naive": "{{nature}}",
|
||||
"Modest": "{{nature}}",
|
||||
"Mild": "{{nature}}",
|
||||
"Quiet": "{{nature}}",
|
||||
"Bashful": "{{nature}}",
|
||||
"Rash": "{{nature}}",
|
||||
"Calm": "{{nature}}",
|
||||
"Gentle": "{{nature}}",
|
||||
"Sassy": "{{nature}}",
|
||||
"Careful": "{{nature}}",
|
||||
"Quirky": "{{nature}}"
|
||||
}
|
||||
}
|
||||
|
@ -28,10 +28,10 @@
|
||||
"SPDshortened": "速さ",
|
||||
"runInfo": "ラン情報",
|
||||
"money": "お金",
|
||||
"runLength": "ラン最高ウェーブ",
|
||||
"viewHeldItems": "手持ちアイテム",
|
||||
"hallofFameText": "殿堂へようこそ!",
|
||||
"hallofFameText_female": "殿堂へようこそ!",
|
||||
"runLength": "時間",
|
||||
"viewHeldItems": "持たせたアイテム",
|
||||
"hallofFameText": "殿堂入り おめでとう!",
|
||||
"hallofFameText_female": "殿堂入り おめでとう!",
|
||||
"viewHallOfFame": "殿堂登録を見る!",
|
||||
"viewEndingSplash": "クリア後のアートを見る!"
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"overwriteData": "選択した スロットに データを 上書きします?",
|
||||
"loading": "読込中…",
|
||||
"wave": "波",
|
||||
"wave": "ラウンド",
|
||||
"lv": "Lv",
|
||||
"empty": "なし"
|
||||
}
|
||||
}
|
||||
|
@ -100,7 +100,7 @@
|
||||
"moveTouchControls": "タッチ移動操作",
|
||||
"shopOverlayOpacity": "ショップオーバレイ不透明度",
|
||||
"shopCursorTarget": "ショップカーソル初位置",
|
||||
"items": "アイテム",
|
||||
"rewards": "ご褒美",
|
||||
"reroll": "選択肢変更",
|
||||
"shop": "ショップ",
|
||||
"checkTeam": "手持ちを確認"
|
||||
|
@ -1 +1,36 @@
|
||||
{}
|
||||
{
|
||||
"battlesWon": "Battles Won!",
|
||||
"joinTheDiscord": "Join the Discord!",
|
||||
"infiniteLevels": "Infinite Levels!",
|
||||
"everythingStacks": "Everything Stacks!",
|
||||
"optionalSaveScumming": "Optional Save Scumming!",
|
||||
"biomes": "35 Biomes!",
|
||||
"openSource": "Open Source!",
|
||||
"playWithSpeed": "Play with 5x Speed!",
|
||||
"liveBugTesting": "Live Bug Testing!",
|
||||
"heavyInfluence": "Heavy RoR2 Influence!",
|
||||
"pokemonRiskAndPokemonRain": "Pokémon Risk and Pokémon Rain!",
|
||||
"nowWithMoreSalt": "Now with 33% More Salt!",
|
||||
"infiniteFusionAtHome": "Infinite Fusion at Home!",
|
||||
"brokenEggMoves": "Broken Egg Moves!",
|
||||
"magnificent": "Magnificent!",
|
||||
"mubstitute": "Mubstitute!",
|
||||
"thatsCrazy": "That's Crazy!",
|
||||
"oranceJuice": "Orance Juice!",
|
||||
"questionableBalancing": "Questionable Balancing!",
|
||||
"coolShaders": "Cool Shaders!",
|
||||
"aiFree": "AI-Free!",
|
||||
"suddenDifficultySpikes": "Sudden Difficulty Spikes!",
|
||||
"basedOnAnUnfinishedFlashGame": "Based on an Unfinished Flash Game!",
|
||||
"moreAddictiveThanIntended": "More Addictive than Intended!",
|
||||
"mostlyConsistentSeeds": "Mostly Consistent Seeds!",
|
||||
"achievementPointsDontDoAnything": "Achievement Points Don't Do Anything!",
|
||||
"youDoNotStartAtLevel": "You Do Not Start at Level 2000!",
|
||||
"dontTalkAboutTheManaphyEggIncident": "Don't Talk About the Manaphy Egg Incident!",
|
||||
"alsoTryPokengine": "Also Try Pokéngine!",
|
||||
"alsoTryEmeraldRogue": "Also Try Emerald Rogue!",
|
||||
"alsoTryRadicalRed": "Also Try Radical Red!",
|
||||
"eeveeExpo": "Eevee Expo!",
|
||||
"ynoproject": "YNOproject!",
|
||||
"breedersInSpace": "Breeders in space!"
|
||||
}
|
||||
|
@ -16,17 +16,17 @@
|
||||
"snowStartMessage": "雪が 降り始めた!",
|
||||
"snowLapseMessage": "雪が 降っている!",
|
||||
"snowClearMessage": "雪が 止んだ!",
|
||||
"fogStartMessage": "足下に 霧(きり)が立ち込めた!",
|
||||
"fogLapseMessage": "足下に 霧(きり)が 立ち込めている!",
|
||||
"fogClearMessage": "足下の 霧(きり)が消え去った!",
|
||||
"fogStartMessage": "足下に 霧が 立ち込めた!",
|
||||
"fogLapseMessage": "足下に 霧が 立ち込めている!",
|
||||
"fogClearMessage": "足下の 霧が 消え去った!",
|
||||
"heavyRainStartMessage": "強い雨が 降り始めた!",
|
||||
"heavyRainLapseMessage": "強い雨が 降っている!",
|
||||
"heavyRainClearMessage": "強い雨が あがった!",
|
||||
"harshSunStartMessage": "日差しが とても強くなった!",
|
||||
"harshSunLapseMessage": "日差しが とても強い!",
|
||||
"harshSunClearMessage": "日差しが 元に戻った!",
|
||||
"strongWindsStartMessage": "謎(なぞ)の 乱気流(らんきりゅう)が\nひこうポケモンを 護(まも)る!",
|
||||
"strongWindsLapseMessage": "謎(なぞ)の 乱気流(らんきりゅう)の 勢(いきお)いは 止まらない!",
|
||||
"strongWindsEffectMessage": "謎(なぞ)の 乱気流(らんきりゅう)が 攻撃(こうげき)を 弱(よわ)めた!",
|
||||
"strongWindsClearMessage": "謎(なぞ)の 乱気流(らんきりゅう)が おさまった!"
|
||||
}
|
||||
"strongWindsStartMessage": "謎の 乱気流が\nひこうポケモンを 護る!",
|
||||
"strongWindsLapseMessage": "謎の 乱気流の 勢いは 止まらない!",
|
||||
"strongWindsEffectMessage": "謎の 乱気流が 攻撃を 弱めた!",
|
||||
"strongWindsClearMessage": "謎の 乱気流が おさまった!"
|
||||
}
|
||||
|
@ -36,5 +36,6 @@
|
||||
"matBlock": "마룻바닥세워막기",
|
||||
"craftyShield": "트릭가드",
|
||||
"tailwind": "순풍",
|
||||
"happyHour": "해피타임"
|
||||
}
|
||||
"happyHour": "해피타임",
|
||||
"safeguard": "신비의부적"
|
||||
}
|
||||
|
@ -100,7 +100,7 @@
|
||||
"moveTouchControls": "터치 컨트롤 이동",
|
||||
"shopOverlayOpacity": "상점 오버레이 투명도",
|
||||
"shopCursorTarget": "상점 커서 위치",
|
||||
"items": "아이템",
|
||||
"rewards": "아이템",
|
||||
"reroll": "갱신",
|
||||
"shop": "상점",
|
||||
"checkTeam": "파티 확인"
|
||||
|
@ -36,5 +36,6 @@
|
||||
"matBlock": "Mat Block",
|
||||
"craftyShield": "Crafty Shield",
|
||||
"tailwind": "Tailwind",
|
||||
"happyHour": "Happy Hour"
|
||||
"happyHour": "Happy Hour",
|
||||
"safeguard": "Safeguard"
|
||||
}
|
||||
|
@ -100,7 +100,7 @@
|
||||
"moveTouchControls": "Mover Controles de Toque",
|
||||
"shopOverlayOpacity": "Opacidade da Loja",
|
||||
"shopCursorTarget": "Alvo do Cursor da Loja",
|
||||
"items": "Itens",
|
||||
"rewards": "Itens",
|
||||
"reroll": "Atualizar",
|
||||
"shop": "Loja",
|
||||
"checkTeam": "Checar Time"
|
||||
|
@ -36,5 +36,6 @@
|
||||
"matBlock": "掀榻榻米",
|
||||
"craftyShield": "戏法防守",
|
||||
"tailwind": "顺风",
|
||||
"happyHour": "快乐时光"
|
||||
}
|
||||
"happyHour": "快乐时光",
|
||||
"safeguard": "神秘守护"
|
||||
}
|
||||
|
@ -99,7 +99,7 @@
|
||||
"moveTouchControls": "移动触摸控制",
|
||||
"shopOverlayOpacity": "商店显示不透明度",
|
||||
"shopCursorTarget": "商店指针位置",
|
||||
"items": "道具",
|
||||
"rewards": "道具",
|
||||
"reroll": "刷新",
|
||||
"shop": "购买",
|
||||
"checkTeam": "检查队伍"
|
||||
|
@ -2488,7 +2488,7 @@ export class TurnHeldItemTransferModifier extends HeldItemTransferModifier {
|
||||
}
|
||||
|
||||
getTransferMessage(pokemon: Pokemon, targetPokemon: Pokemon, item: ModifierTypes.ModifierType): string {
|
||||
return i18next.t("modifier:turnHeldItemTransferApply", { pokemonNameWithAffix: getPokemonNameWithAffix(targetPokemon), itemName: item.name, pokemonName: pokemon.name, typeName: this.type.name });
|
||||
return i18next.t("modifier:turnHeldItemTransferApply", { pokemonNameWithAffix: getPokemonNameWithAffix(targetPokemon), itemName: item.name, pokemonName: pokemon.getNameToRender(), typeName: this.type.name });
|
||||
}
|
||||
|
||||
getMaxHeldItemCount(pokemon: Pokemon): integer {
|
||||
|
@ -1,31 +1,34 @@
|
||||
import BattleScene from "#app/battle-scene.js";
|
||||
import { applyAbAttrs, RunSuccessAbAttr } from "#app/data/ability.js";
|
||||
import { Stat } from "#app/enums/stat.js";
|
||||
import { StatusEffect } from "#app/enums/status-effect.js";
|
||||
import Pokemon from "#app/field/pokemon.js";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import { applyAbAttrs, RunSuccessAbAttr } from "#app/data/ability";
|
||||
import { Stat } from "#app/enums/stat";
|
||||
import { StatusEffect } from "#app/enums/status-effect";
|
||||
import Pokemon, { PlayerPokemon, EnemyPokemon } from "#app/field/pokemon";
|
||||
import i18next from "i18next";
|
||||
import * as Utils from "#app/utils.js";
|
||||
import * as Utils from "#app/utils";
|
||||
import { BattleEndPhase } from "./battle-end-phase";
|
||||
import { NewBattlePhase } from "./new-battle-phase";
|
||||
import { PokemonPhase } from "./pokemon-phase";
|
||||
|
||||
export class AttemptRunPhase extends PokemonPhase {
|
||||
constructor(scene: BattleScene, fieldIndex: integer) {
|
||||
constructor(scene: BattleScene, fieldIndex: number) {
|
||||
super(scene, fieldIndex);
|
||||
}
|
||||
|
||||
start() {
|
||||
super.start();
|
||||
|
||||
const playerPokemon = this.getPokemon();
|
||||
const playerField = this.scene.getPlayerField();
|
||||
const enemyField = this.scene.getEnemyField();
|
||||
|
||||
const enemySpeed = enemyField.reduce((total: integer, enemyPokemon: Pokemon) => total + enemyPokemon.getStat(Stat.SPD), 0) / enemyField.length;
|
||||
const playerPokemon = this.getPokemon();
|
||||
|
||||
const escapeChance = new Utils.NumberHolder(0);
|
||||
|
||||
this.attemptRunAway(playerField, enemyField, escapeChance);
|
||||
|
||||
const escapeChance = new Utils.IntegerHolder((((playerPokemon.getStat(Stat.SPD) * 128) / enemySpeed) + (30 * this.scene.currentBattle.escapeAttempts++)) % 256);
|
||||
applyAbAttrs(RunSuccessAbAttr, playerPokemon, null, false, escapeChance);
|
||||
|
||||
if (playerPokemon.randSeedInt(256) < escapeChance.value) {
|
||||
if (Utils.randSeedInt(100) < escapeChance.value) {
|
||||
this.scene.playSound("se/flee");
|
||||
this.scene.queueMessage(i18next.t("battle:runAwaySuccess"), null, true, 500);
|
||||
|
||||
@ -53,4 +56,48 @@ export class AttemptRunPhase extends PokemonPhase {
|
||||
|
||||
this.end();
|
||||
}
|
||||
|
||||
attemptRunAway(playerField: PlayerPokemon[], enemyField: EnemyPokemon[], escapeChance: Utils.NumberHolder) {
|
||||
/** Sum of the speed of all enemy pokemon on the field */
|
||||
const enemySpeed = enemyField.reduce((total: number, enemyPokemon: Pokemon) => total + enemyPokemon.getStat(Stat.SPD), 0);
|
||||
/** Sum of the speed of all player pokemon on the field */
|
||||
const playerSpeed = playerField.reduce((total: number, playerPokemon: Pokemon) => total + playerPokemon.getStat(Stat.SPD), 0);
|
||||
|
||||
/* The way the escape chance works is by looking at the difference between your speed and the enemy field's average speed as a ratio. The higher this ratio, the higher your chance of success.
|
||||
* However, there is a cap for the ratio of your speed vs enemy speed which beyond that point, you won't gain any advantage. It also looks at how many times you've tried to escape.
|
||||
* Again, the more times you've tried to escape, the higher your odds of escaping. Bosses and non-bosses are calculated differently - bosses are harder to escape from vs non-bosses
|
||||
* Finally, there's a minimum and maximum escape chance as well so that escapes aren't guaranteed, yet they are never 0 either.
|
||||
* The percentage chance to escape from a pokemon for both bosses and non bosses is linear and based on the minimum and maximum chances, and the speed ratio cap.
|
||||
*
|
||||
* At the time of writing, these conditions should be met:
|
||||
* - The minimum escape chance should be 5% for bosses and non bosses
|
||||
* - Bosses should have a maximum escape chance of 25%, whereas non-bosses should be 95%
|
||||
* - The bonus per previous escape attempt should be 2% for bosses and 10% for non-bosses
|
||||
* - The speed ratio cap should be 6x for bosses and 4x for non-bosses
|
||||
* - The "default" escape chance when your speed equals the enemy speed should be 8.33% for bosses and 27.5% for non-bosses
|
||||
*
|
||||
* From the above, we can calculate the below values
|
||||
*/
|
||||
|
||||
let isBoss = false;
|
||||
for (let e = 0; e < enemyField.length; e++) {
|
||||
isBoss = isBoss || enemyField[e].isBoss(); // this line checks if any of the enemy pokemon on the field are bosses; if so, the calculation for escaping is different
|
||||
}
|
||||
|
||||
/** The ratio between the speed of your active pokemon and the speed of the enemy field */
|
||||
const speedRatio = playerSpeed / enemySpeed;
|
||||
/** The max ratio before escape chance stops increasing. Increased if there is a boss on the field */
|
||||
const speedCap = isBoss ? 6 : 4;
|
||||
/** Minimum percent chance to escape */
|
||||
const minChance = 5;
|
||||
/** Maximum percent chance to escape. Decreased if a boss is on the field */
|
||||
const maxChance = isBoss ? 25 : 95;
|
||||
/** How much each escape attempt increases the chance of the next attempt. Decreased if a boss is on the field */
|
||||
const escapeBonus = isBoss ? 2 : 10;
|
||||
/** Slope of the escape chance curve */
|
||||
const escapeSlope = (maxChance - minChance) / speedCap;
|
||||
|
||||
// This will calculate the escape chance given all of the above and clamp it to the range of [`minChance`, `maxChance`]
|
||||
escapeChance.value = Phaser.Math.Clamp(Math.round((escapeSlope * speedRatio) + minChance + (escapeBonus * this.scene.currentBattle.escapeAttempts++)), minChance, maxChance);
|
||||
}
|
||||
}
|
||||
|
@ -107,8 +107,9 @@ export class CommandPhase extends FieldPhase {
|
||||
|
||||
// Decides between a Disabled, Not Implemented, or No PP translation message
|
||||
const errorMessage =
|
||||
playerPokemon.summonData.disabledMove === move.moveId ? "battle:moveDisabled" :
|
||||
move.getName().endsWith(" (N)") ? "battle:moveNotImplemented" : "battle:moveNoPP";
|
||||
playerPokemon.isMoveRestricted(move.moveId)
|
||||
? playerPokemon.getRestrictingTag(move.moveId)!.selectionDeniedText(playerPokemon, move.moveId)
|
||||
: move.getName().endsWith(" (N)") ? "battle:moveNotImplemented" : "battle:moveNoPP";
|
||||
const moveName = move.getName().replace(" (N)", ""); // Trims off the indicator
|
||||
|
||||
this.scene.ui.showText(i18next.t(errorMessage, { moveName: moveName }), null, () => {
|
||||
|
@ -1,23 +1,29 @@
|
||||
import BattleScene, { AnySound } from "#app/battle-scene.js";
|
||||
import { Egg, EGG_SEED } from "#app/data/egg.js";
|
||||
import { EggCountChangedEvent } from "#app/events/egg.js";
|
||||
import { PlayerPokemon } from "#app/field/pokemon.js";
|
||||
import { getPokemonNameWithAffix } from "#app/messages.js";
|
||||
import { Phase } from "#app/phase.js";
|
||||
import { achvs } from "#app/system/achv.js";
|
||||
import EggCounterContainer from "#app/ui/egg-counter-container.js";
|
||||
import EggHatchSceneHandler from "#app/ui/egg-hatch-scene-handler.js";
|
||||
import PokemonInfoContainer from "#app/ui/pokemon-info-container.js";
|
||||
import { Mode } from "#app/ui/ui.js";
|
||||
import BattleScene, { AnySound } from "#app/battle-scene";
|
||||
import { Egg } from "#app/data/egg";
|
||||
import { EggCountChangedEvent } from "#app/events/egg";
|
||||
import { PlayerPokemon } from "#app/field/pokemon";
|
||||
import { getPokemonNameWithAffix } from "#app/messages";
|
||||
import { Phase } from "#app/phase";
|
||||
import { achvs } from "#app/system/achv";
|
||||
import EggCounterContainer from "#app/ui/egg-counter-container";
|
||||
import EggHatchSceneHandler from "#app/ui/egg-hatch-scene-handler";
|
||||
import PokemonInfoContainer from "#app/ui/pokemon-info-container";
|
||||
import { Mode } from "#app/ui/ui";
|
||||
import i18next from "i18next";
|
||||
import SoundFade from "phaser3-rex-plugins/plugins/soundfade";
|
||||
import * as Utils from "#app/utils.js";
|
||||
import * as Utils from "#app/utils";
|
||||
import { EggLapsePhase } from "./egg-lapse-phase";
|
||||
import { EggHatchData } from "#app/data/egg-hatch-data";
|
||||
|
||||
|
||||
/**
|
||||
* Class that represents egg hatching
|
||||
*/
|
||||
export class EggHatchPhase extends Phase {
|
||||
/** The egg that is hatching */
|
||||
private egg: Egg;
|
||||
/** The new EggHatchData for the egg/pokemon that hatches */
|
||||
private eggHatchData: EggHatchData;
|
||||
|
||||
/** The number of eggs that are hatching */
|
||||
private eggsToHatchCount: integer;
|
||||
@ -58,10 +64,11 @@ export class EggHatchPhase extends Phase {
|
||||
private skipped: boolean;
|
||||
/** The sound effect being played when the egg is hatched */
|
||||
private evolutionBgm: AnySound;
|
||||
private eggLapsePhase: EggLapsePhase;
|
||||
|
||||
constructor(scene: BattleScene, egg: Egg, eggsToHatchCount: integer) {
|
||||
constructor(scene: BattleScene, hatchScene: EggLapsePhase, egg: Egg, eggsToHatchCount: integer) {
|
||||
super(scene);
|
||||
|
||||
this.eggLapsePhase = hatchScene;
|
||||
this.egg = egg;
|
||||
this.eggsToHatchCount = eggsToHatchCount;
|
||||
}
|
||||
@ -307,6 +314,7 @@ export class EggHatchPhase extends Phase {
|
||||
* Function to do the logic and animation of completing a hatch and revealing the Pokemon
|
||||
*/
|
||||
doReveal(): void {
|
||||
// set the previous dex data so info container can show new unlocks in egg summary
|
||||
const isShiny = this.pokemon.isShiny();
|
||||
if (this.pokemon.species.subLegendary) {
|
||||
this.scene.validateAchv(achvs.HATCH_SUB_LEGENDARY);
|
||||
@ -345,13 +353,13 @@ export class EggHatchPhase extends Phase {
|
||||
this.scene.ui.showText(i18next.t("egg:hatchFromTheEgg", { pokemonName: getPokemonNameWithAffix(this.pokemon) }), null, () => {
|
||||
this.scene.gameData.updateSpeciesDexIvs(this.pokemon.species.speciesId, this.pokemon.ivs);
|
||||
this.scene.gameData.setPokemonCaught(this.pokemon, true, true).then(() => {
|
||||
this.scene.gameData.setEggMoveUnlocked(this.pokemon.species, this.eggMoveIndex).then(() => {
|
||||
this.scene.gameData.setEggMoveUnlocked(this.pokemon.species, this.eggMoveIndex).then((value) => {
|
||||
this.eggHatchData.setEggMoveUnlocked(value);
|
||||
this.scene.ui.showText("", 0);
|
||||
this.end();
|
||||
});
|
||||
});
|
||||
}, null, true, 3000);
|
||||
//this.scene.time.delayedCall(Utils.fixedInt(4250), () => this.scene.playBgm());
|
||||
});
|
||||
});
|
||||
this.scene.tweens.add({
|
||||
@ -435,17 +443,11 @@ export class EggHatchPhase extends Phase {
|
||||
|
||||
/**
|
||||
* Generates a Pokemon to be hatched by the egg
|
||||
* Also stores the generated pokemon in this.eggHatchData
|
||||
* @returns the hatched PlayerPokemon
|
||||
*/
|
||||
generatePokemon(): PlayerPokemon {
|
||||
let ret: PlayerPokemon;
|
||||
|
||||
this.scene.executeWithSeedOffset(() => {
|
||||
ret = this.egg.generatePlayerPokemon(this.scene);
|
||||
this.eggMoveIndex = this.egg.eggMoveIndex;
|
||||
|
||||
}, this.egg.id, EGG_SEED.toString());
|
||||
|
||||
return ret!;
|
||||
this.eggHatchData = this.eggLapsePhase.generatePokemon(this.egg);
|
||||
return this.eggHatchData.pokemon;
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,23 @@
|
||||
import BattleScene from "#app/battle-scene.js";
|
||||
import { Egg } from "#app/data/egg.js";
|
||||
import { Phase } from "#app/phase.js";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import { Egg, EGG_SEED } from "#app/data/egg";
|
||||
import { Phase } from "#app/phase";
|
||||
import i18next from "i18next";
|
||||
import Overrides from "#app/overrides";
|
||||
import { EggHatchPhase } from "./egg-hatch-phase";
|
||||
import { Mode } from "#app/ui/ui";
|
||||
import { achvs } from "#app/system/achv";
|
||||
import { PlayerPokemon } from "#app/field/pokemon";
|
||||
import { EggSummaryPhase } from "./egg-summary-phase";
|
||||
import { EggHatchData } from "#app/data/egg-hatch-data";
|
||||
|
||||
/**
|
||||
* Phase that handles updating eggs, and hatching any ready eggs
|
||||
* Also handles prompts for skipping animation, and calling the egg summary phase
|
||||
*/
|
||||
export class EggLapsePhase extends Phase {
|
||||
|
||||
private eggHatchData: EggHatchData[] = [];
|
||||
private readonly minEggsToPromptSkip: number = 5;
|
||||
constructor(scene: BattleScene) {
|
||||
super(scene);
|
||||
}
|
||||
@ -16,20 +28,111 @@ export class EggLapsePhase extends Phase {
|
||||
const eggsToHatch: Egg[] = this.scene.gameData.eggs.filter((egg: Egg) => {
|
||||
return Overrides.EGG_IMMEDIATE_HATCH_OVERRIDE ? true : --egg.hatchWaves < 1;
|
||||
});
|
||||
const eggsToHatchCount: number = eggsToHatch.length;
|
||||
this.eggHatchData= [];
|
||||
|
||||
let eggCount: integer = eggsToHatch.length;
|
||||
if (eggsToHatchCount > 0) {
|
||||
|
||||
if (eggCount) {
|
||||
this.scene.queueMessage(i18next.t("battle:eggHatching"));
|
||||
|
||||
for (const egg of eggsToHatch) {
|
||||
this.scene.unshiftPhase(new EggHatchPhase(this.scene, egg, eggCount));
|
||||
if (eggCount > 0) {
|
||||
eggCount--;
|
||||
}
|
||||
if (eggsToHatchCount >= this.minEggsToPromptSkip) {
|
||||
this.scene.ui.showText(i18next.t("battle:eggHatching"), 0, () => {
|
||||
// show prompt for skip
|
||||
this.scene.ui.showText(i18next.t("battle:eggSkipPrompt"), 0);
|
||||
this.scene.ui.setModeWithoutClear(Mode.CONFIRM, () => {
|
||||
this.hatchEggsSkipped(eggsToHatch);
|
||||
this.showSummary();
|
||||
}, () => {
|
||||
this.hatchEggsRegular(eggsToHatch);
|
||||
this.showSummary();
|
||||
}
|
||||
);
|
||||
}, 100, true);
|
||||
} else {
|
||||
// regular hatches, no summary
|
||||
this.scene.queueMessage(i18next.t("battle:eggHatching"));
|
||||
this.hatchEggsRegular(eggsToHatch);
|
||||
this.end();
|
||||
}
|
||||
|
||||
} else {
|
||||
this.end();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hatches eggs normally one by one, showing animations
|
||||
* @param eggsToHatch list of eggs to hatch
|
||||
*/
|
||||
hatchEggsRegular(eggsToHatch: Egg[]) {
|
||||
let eggsToHatchCount: number = eggsToHatch.length;
|
||||
for (const egg of eggsToHatch) {
|
||||
this.scene.unshiftPhase(new EggHatchPhase(this.scene, this, egg, eggsToHatchCount));
|
||||
eggsToHatchCount--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hatches eggs with no animations
|
||||
* @param eggsToHatch list of eggs to hatch
|
||||
*/
|
||||
hatchEggsSkipped(eggsToHatch: Egg[]) {
|
||||
for (const egg of eggsToHatch) {
|
||||
this.hatchEggSilently(egg);
|
||||
}
|
||||
}
|
||||
|
||||
showSummary() {
|
||||
this.scene.unshiftPhase(new EggSummaryPhase(this.scene, this.eggHatchData));
|
||||
this.end();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hatches an egg and stores it in the local EggHatchData array without animations
|
||||
* Also validates the achievements for the hatched pokemon and removes the egg
|
||||
* @param egg egg to hatch
|
||||
*/
|
||||
hatchEggSilently(egg: Egg) {
|
||||
const eggIndex = this.scene.gameData.eggs.findIndex(e => e.id === egg.id);
|
||||
if (eggIndex === -1) {
|
||||
return this.end();
|
||||
}
|
||||
this.scene.gameData.eggs.splice(eggIndex, 1);
|
||||
|
||||
const data = this.generatePokemon(egg);
|
||||
const pokemon = data.pokemon;
|
||||
if (pokemon.fusionSpecies) {
|
||||
pokemon.clearFusionSpecies();
|
||||
}
|
||||
|
||||
if (pokemon.species.subLegendary) {
|
||||
this.scene.validateAchv(achvs.HATCH_SUB_LEGENDARY);
|
||||
}
|
||||
if (pokemon.species.legendary) {
|
||||
this.scene.validateAchv(achvs.HATCH_LEGENDARY);
|
||||
}
|
||||
if (pokemon.species.mythical) {
|
||||
this.scene.validateAchv(achvs.HATCH_MYTHICAL);
|
||||
}
|
||||
if (pokemon.isShiny()) {
|
||||
this.scene.validateAchv(achvs.HATCH_SHINY);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a Pokemon and creates a new EggHatchData instance for the given egg
|
||||
* @param egg the egg to hatch
|
||||
* @returns the hatched PlayerPokemon
|
||||
*/
|
||||
generatePokemon(egg: Egg): EggHatchData {
|
||||
let ret: PlayerPokemon;
|
||||
let newHatchData: EggHatchData;
|
||||
this.scene.executeWithSeedOffset(() => {
|
||||
ret = egg.generatePlayerPokemon(this.scene);
|
||||
newHatchData = new EggHatchData(this.scene, ret, egg.eggMoveIndex);
|
||||
newHatchData.setDex();
|
||||
this.eggHatchData.push(newHatchData);
|
||||
|
||||
}, egg.id, EGG_SEED.toString());
|
||||
return newHatchData!;
|
||||
}
|
||||
|
||||
}
|
||||
|
50
src/phases/egg-summary-phase.ts
Normal file
@ -0,0 +1,50 @@
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import { Phase } from "#app/phase";
|
||||
import { Mode } from "#app/ui/ui";
|
||||
import EggHatchSceneHandler from "#app/ui/egg-hatch-scene-handler";
|
||||
import { EggHatchData } from "#app/data/egg-hatch-data";
|
||||
|
||||
/**
|
||||
* Class that represents the egg summary phase
|
||||
* It does some of the function for updating egg data
|
||||
* Phase is handled mostly by the egg-hatch-scene-handler UI
|
||||
*/
|
||||
export class EggSummaryPhase extends Phase {
|
||||
private eggHatchData: EggHatchData[];
|
||||
private eggHatchHandler: EggHatchSceneHandler;
|
||||
|
||||
constructor(scene: BattleScene, eggHatchData: EggHatchData[]) {
|
||||
super(scene);
|
||||
this.eggHatchData = eggHatchData;
|
||||
}
|
||||
|
||||
start() {
|
||||
super.start();
|
||||
|
||||
// updates next pokemon once the current update has been completed
|
||||
const updateNextPokemon = (i: number) => {
|
||||
if (i >= this.eggHatchData.length) {
|
||||
this.scene.ui.setModeForceTransition(Mode.EGG_HATCH_SUMMARY, this.eggHatchData).then(() => {
|
||||
this.scene.fadeOutBgm(undefined, false);
|
||||
this.eggHatchHandler = this.scene.ui.getHandler() as EggHatchSceneHandler;
|
||||
});
|
||||
|
||||
} else {
|
||||
this.eggHatchData[i].setDex();
|
||||
this.eggHatchData[i].updatePokemon().then(() => {
|
||||
if (i < this.eggHatchData.length) {
|
||||
updateNextPokemon(i + 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
updateNextPokemon(0);
|
||||
|
||||
}
|
||||
|
||||
end() {
|
||||
this.eggHatchHandler.clear();
|
||||
this.scene.ui.setModeForceTransition(Mode.MESSAGE).then(() => {});
|
||||
super.end();
|
||||
}
|
||||
}
|
@ -77,4 +77,8 @@ export class EnemyCommandPhase extends FieldPhase {
|
||||
|
||||
this.end();
|
||||
}
|
||||
|
||||
getFieldIndex(): number {
|
||||
return this.fieldIndex;
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +49,9 @@ export class GameOverPhase extends BattlePhase {
|
||||
}
|
||||
|
||||
if (this.victory && this.scene.gameMode.isEndless) {
|
||||
this.scene.ui.showDialogue(i18next.t("PGMmiscDialogue:ending_endless"), i18next.t("PGMmiscDialogue:ending_name"), 0, () => this.handleGameOver());
|
||||
const genderIndex = this.scene.gameData.gender ?? PlayerGender.UNSET;
|
||||
const genderStr = PlayerGender[genderIndex].toLowerCase();
|
||||
this.scene.ui.showDialogue(i18next.t("miscDialogue:ending_endless", { context: genderStr }), i18next.t("miscDialogue:ending_name"), 0, () => this.handleGameOver());
|
||||
} else if (this.victory || !this.scene.enableRetries) {
|
||||
this.handleGameOver();
|
||||
} else {
|
||||
|
@ -377,16 +377,16 @@ export class MoveEffectPhase extends PokemonPhase {
|
||||
return false;
|
||||
}
|
||||
|
||||
const moveAccuracy = this.move.getMove().calculateBattleAccuracy(user!, target); // TODO: is the bang correct here?
|
||||
const moveAccuracy = this.move.getMove().calculateBattleAccuracy(user, target);
|
||||
|
||||
if (moveAccuracy === -1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const accuracyMultiplier = user.getAccuracyMultiplier(target, this.move.getMove());
|
||||
const rand = user.randSeedInt(100, 1);
|
||||
const rand = user.randSeedInt(100);
|
||||
|
||||
return rand <= moveAccuracy * (accuracyMultiplier!); // TODO: is this bang correct?
|
||||
return rand < (moveAccuracy * accuracyMultiplier);
|
||||
}
|
||||
|
||||
/** Returns the {@linkcode Pokemon} using this phase's invoked move */
|
||||
|
@ -44,8 +44,8 @@ export class MovePhase extends BattlePhase {
|
||||
this.cancelled = false;
|
||||
}
|
||||
|
||||
canMove(): boolean {
|
||||
return this.pokemon.isActive(true) && this.move.isUsable(this.pokemon, this.ignorePp) && !!this.targets.length;
|
||||
canMove(ignoreDisableTags?: boolean): boolean {
|
||||
return this.pokemon.isActive(true) && this.move.isUsable(this.pokemon, this.ignorePp, ignoreDisableTags) && !!this.targets.length;
|
||||
}
|
||||
|
||||
/**Signifies the current move should fail but still use PP */
|
||||
@ -63,10 +63,7 @@ export class MovePhase extends BattlePhase {
|
||||
|
||||
console.log(Moves[this.move.moveId]);
|
||||
|
||||
if (!this.canMove()) {
|
||||
if (this.move.moveId && this.pokemon.summonData?.disabledMove === this.move.moveId) {
|
||||
this.scene.queueMessage(i18next.t("battle:moveDisabled", { moveName: this.move.getName() }));
|
||||
}
|
||||
if (!this.canMove(true)) {
|
||||
if (this.pokemon.isActive(true) && this.move.ppUsed >= this.move.getMovePp()) { // if the move PP was reduced from Spite or otherwise, the move fails
|
||||
this.fail();
|
||||
this.showMoveText();
|
||||
|
@ -1,9 +1,7 @@
|
||||
import BattleScene from "#app/battle-scene.js";
|
||||
import { applyPostTurnAbAttrs, PostTurnAbAttr } from "#app/data/ability.js";
|
||||
import { BattlerTagLapseType } from "#app/data/battler-tags.js";
|
||||
import { allMoves } from "#app/data/move.js";
|
||||
import { TerrainType } from "#app/data/terrain.js";
|
||||
import { Moves } from "#app/enums/moves.js";
|
||||
import { WeatherType } from "#app/enums/weather-type.js";
|
||||
import { TurnEndEvent } from "#app/events/battle-scene.js";
|
||||
import Pokemon from "#app/field/pokemon.js";
|
||||
@ -11,7 +9,6 @@ import { getPokemonNameWithAffix } from "#app/messages.js";
|
||||
import { TurnHealModifier, EnemyTurnHealModifier, EnemyStatusEffectHealChanceModifier, TurnStatusEffectModifier, TurnHeldItemTransferModifier } from "#app/modifier/modifier.js";
|
||||
import i18next from "i18next";
|
||||
import { FieldPhase } from "./field-phase";
|
||||
import { MessagePhase } from "./message-phase";
|
||||
import { PokemonHealPhase } from "./pokemon-heal-phase";
|
||||
|
||||
export class TurnEndPhase extends FieldPhase {
|
||||
@ -28,11 +25,6 @@ export class TurnEndPhase extends FieldPhase {
|
||||
const handlePokemon = (pokemon: Pokemon) => {
|
||||
pokemon.lapseTags(BattlerTagLapseType.TURN_END);
|
||||
|
||||
if (pokemon.summonData.disabledMove && !--pokemon.summonData.disabledTurns) {
|
||||
this.scene.pushPhase(new MessagePhase(this.scene, i18next.t("battle:notDisabled", { pokemonName: getPokemonNameWithAffix(pokemon), moveName: allMoves[pokemon.summonData.disabledMove].name })));
|
||||
pokemon.summonData.disabledMove = Moves.NONE;
|
||||
}
|
||||
|
||||
this.scene.applyModifiers(TurnHealModifier, pokemon.isPlayer(), pokemon);
|
||||
|
||||
if (this.scene.arena.terrain?.terrainType === TerrainType.GRASSY && pokemon.isGrounded()) {
|
||||
|
@ -1,10 +1,11 @@
|
||||
import BattleScene from "#app/battle-scene.js";
|
||||
import BattleScene from "#app/battle-scene";
|
||||
import { applyPreWeatherEffectAbAttrs, SuppressWeatherEffectAbAttr, PreWeatherDamageAbAttr, applyAbAttrs, BlockNonDirectDamageAbAttr, applyPostWeatherLapseAbAttrs, PostWeatherLapseAbAttr } from "#app/data/ability.js";
|
||||
import { CommonAnim } from "#app/data/battle-anims.js";
|
||||
import { Weather, getWeatherDamageMessage, getWeatherLapseMessage } from "#app/data/weather.js";
|
||||
import { WeatherType } from "#app/enums/weather-type.js";
|
||||
import Pokemon, { HitResult } from "#app/field/pokemon.js";
|
||||
import * as Utils from "#app/utils.js";
|
||||
import { CommonAnim } from "#app/data/battle-anims";
|
||||
import { Weather, getWeatherDamageMessage, getWeatherLapseMessage } from "#app/data/weather";
|
||||
import { BattlerTagType } from "#app/enums/battler-tag-type.js";
|
||||
import { WeatherType } from "#app/enums/weather-type";
|
||||
import Pokemon, { HitResult } from "#app/field/pokemon";
|
||||
import * as Utils from "#app/utils";
|
||||
import { CommonAnimPhase } from "./common-anim-phase";
|
||||
|
||||
export class WeatherEffectPhase extends CommonAnimPhase {
|
||||
@ -39,7 +40,7 @@ export class WeatherEffectPhase extends CommonAnimPhase {
|
||||
applyPreWeatherEffectAbAttrs(PreWeatherDamageAbAttr, pokemon, this.weather, cancelled);
|
||||
applyAbAttrs(BlockNonDirectDamageAbAttr, pokemon, cancelled);
|
||||
|
||||
if (cancelled.value) {
|
||||
if (cancelled.value || pokemon.getTag(BattlerTagType.UNDERGROUND) || pokemon.getTag(BattlerTagType.UNDERWATER)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -857,6 +857,14 @@ export class GameData {
|
||||
|
||||
const settings = JSON.parse(localStorage.getItem("settings")!); // TODO: is this bang correct?
|
||||
|
||||
// TODO: Remove this block after save migration is implemented
|
||||
if (settings.hasOwnProperty("REROLL_TARGET") && !settings.hasOwnProperty(SettingKeys.Shop_Cursor_Target)) {
|
||||
settings[SettingKeys.Shop_Cursor_Target] = settings["REROLL_TARGET"];
|
||||
delete settings["REROLL_TARGET"];
|
||||
localStorage.setItem("settings", JSON.stringify(settings));
|
||||
}
|
||||
// End of block to remove
|
||||
|
||||
for (const setting of Object.keys(settings)) {
|
||||
setSetting(this.scene, setting, settings[setting]);
|
||||
}
|
||||
@ -1553,11 +1561,11 @@ export class GameData {
|
||||
}
|
||||
}
|
||||
|
||||
setPokemonCaught(pokemon: Pokemon, incrementCount: boolean = true, fromEgg: boolean = false): Promise<void> {
|
||||
return this.setPokemonSpeciesCaught(pokemon, pokemon.species, incrementCount, fromEgg);
|
||||
setPokemonCaught(pokemon: Pokemon, incrementCount: boolean = true, fromEgg: boolean = false, showMessage: boolean = true): Promise<void> {
|
||||
return this.setPokemonSpeciesCaught(pokemon, pokemon.species, incrementCount, fromEgg, showMessage);
|
||||
}
|
||||
|
||||
setPokemonSpeciesCaught(pokemon: Pokemon, species: PokemonSpecies, incrementCount: boolean = true, fromEgg: boolean = false): Promise<void> {
|
||||
setPokemonSpeciesCaught(pokemon: Pokemon, species: PokemonSpecies, incrementCount: boolean = true, fromEgg: boolean = false, showMessage: boolean = true): Promise<void> {
|
||||
return new Promise<void>(resolve => {
|
||||
const dexEntry = this.dexData[species.speciesId];
|
||||
const caughtAttr = dexEntry.caughtAttr;
|
||||
@ -1616,13 +1624,17 @@ export class GameData {
|
||||
const checkPrevolution = () => {
|
||||
if (hasPrevolution) {
|
||||
const prevolutionSpecies = pokemonPrevolutions[species.speciesId];
|
||||
return this.setPokemonSpeciesCaught(pokemon, getPokemonSpecies(prevolutionSpecies), incrementCount, fromEgg).then(() => resolve());
|
||||
this.setPokemonSpeciesCaught(pokemon, getPokemonSpecies(prevolutionSpecies), incrementCount, fromEgg, showMessage).then(() => resolve());
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
};
|
||||
|
||||
if (newCatch && speciesStarters.hasOwnProperty(species.speciesId)) {
|
||||
if (!showMessage) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
this.scene.playSound("level_up_fanfare");
|
||||
this.scene.ui.showText(i18next.t("battle:addedAsAStarter", { pokemonName: species.name }), null, () => checkPrevolution(), null, true);
|
||||
} else {
|
||||
@ -1668,7 +1680,7 @@ export class GameData {
|
||||
this.starterData[species.speciesId].candyCount += count;
|
||||
}
|
||||
|
||||
setEggMoveUnlocked(species: PokemonSpecies, eggMoveIndex: integer): Promise<boolean> {
|
||||
setEggMoveUnlocked(species: PokemonSpecies, eggMoveIndex: integer, showMessage: boolean = true): Promise<boolean> {
|
||||
return new Promise<boolean>(resolve => {
|
||||
const speciesId = species.speciesId;
|
||||
if (!speciesEggMoves.hasOwnProperty(speciesId) || !speciesEggMoves[speciesId][eggMoveIndex]) {
|
||||
@ -1688,11 +1700,15 @@ export class GameData {
|
||||
}
|
||||
|
||||
this.starterData[speciesId].eggMoves |= value;
|
||||
|
||||
if (!showMessage) {
|
||||
resolve(true);
|
||||
return;
|
||||
}
|
||||
this.scene.playSound("level_up_fanfare");
|
||||
|
||||
const moveName = allMoves[speciesEggMoves[speciesId][eggMoveIndex]].name;
|
||||
this.scene.ui.showText(eggMoveIndex === 3 ? i18next.t("egg:rareEggMoveUnlock", { moveName: moveName }) : i18next.t("egg:eggMoveUnlock", { moveName: moveName }), null, () => resolve(true), null, true);
|
||||
this.scene.ui.showText(eggMoveIndex === 3 ? i18next.t("egg:rareEggMoveUnlock", { moveName: moveName }) : i18next.t("egg:eggMoveUnlock", { moveName: moveName }), null, (() => {
|
||||
resolve(true);
|
||||
}), null, true);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -127,8 +127,6 @@ export default class PokemonData {
|
||||
this.summonData.stats = source.summonData.stats;
|
||||
this.summonData.statStages = source.summonData.statStages;
|
||||
this.summonData.moveQueue = source.summonData.moveQueue;
|
||||
this.summonData.disabledMove = source.summonData.disabledMove;
|
||||
this.summonData.disabledTurns = source.summonData.disabledTurns;
|
||||
this.summonData.abilitySuppressed = source.summonData.abilitySuppressed;
|
||||
this.summonData.abilitiesApplied = source.summonData.abilitiesApplied;
|
||||
|
||||
|