Merge branch 'beta' into mine

This commit is contained in:
Lylian BALL 2024-09-04 20:04:47 +02:00 committed by GitHub
commit f8e98da011
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
244 changed files with 7032 additions and 4259 deletions

View File

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

View File

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

View File

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

View File

@ -191,15 +191,15 @@ Now that the enemy Pokémon with the best matchup score is on the field (assumin
We then need to apply a 2x multiplier for the move's type effectiveness and a 1.5x multiplier since STAB applies. After applying these multipliers, the final score for this move is **75**. We then need to apply a 2x multiplier for the move's type effectiveness and a 1.5x multiplier since STAB applies. After applying these multipliers, the final score for this move is **75**.
- **Swords Dance**: As a non-attacking move, this move's benefit score is derived entirely from the sum of its attributes' benefit scores. Swords Dance's `StatChangeAttr` has a user benefit score of 0 and a target benefit score that, in this case, simplifies to - **Swords Dance**: As a non-attacking move, this move's benefit score is derived entirely from the sum of its attributes' benefit scores. Swords Dance's `StatStageChangeAttr` has a user benefit score of 0 and a target benefit score that, in this case, simplifies to
$\text{TBS}=4\times \text{levels} + (-2\times \text{sign(levels)})$ $\text{TBS}=4\times \text{levels} + (-2\times \text{sign(levels)})$
where `levels` is the number of stat stages added by the attribute (in this case, +2). The final score for this move is **6** (Note: because this move is self-targeted, we don't flip the sign of TBS when computing the target score). where `levels` is the number of stat stages added by the attribute (in this case, +2). The final score for this move is **6** (Note: because this move is self-targeted, we don't flip the sign of TBS when computing the target score).
- **Crush Claw**: This move is a 75-power Normal-type physical attack with a 50 percent chance to lower the target's Defense by one stage. The additional effect is implemented by the same `StatChangeAttr` as Swords Dance, so we can use the same formulas from before to compute the total TBS and base target score. - **Crush Claw**: This move is a 75-power Normal-type physical attack with a 50 percent chance to lower the target's Defense by one stage. The additional effect is implemented by the same `StatStageChangeAttr` as Swords Dance, so we can use the same formulas from before to compute the total TBS and base target score.
$\text{TBS}=\text{getTargetBenefitScore(StatChangeAttr)}-\text{attackScore}$ $\text{TBS}=\text{getTargetBenefitScore(StatStageChangeAttr)}-\text{attackScore}$
$\text{TBS}=(-4 + 2)-(-2\times 2 + \lfloor \frac{75}{5} \rfloor)=-2-11=-13$ $\text{TBS}=(-4 + 2)-(-2\times 2 + \lfloor \frac{75}{5} \rfloor)=-2-11=-13$
@ -221,4 +221,4 @@ When implementing a new move attribute, it's important to override `MoveAttr`'s
- A move's **user benefit score (UBS)** incentivizes (or discourages) the move's usage in general. A positive UBS gives the move more incentive to be used, while a negative UBS gives the move less incentive. - A move's **user benefit score (UBS)** incentivizes (or discourages) the move's usage in general. A positive UBS gives the move more incentive to be used, while a negative UBS gives the move less incentive.
- A move's **target benefit score (TBS)** incentivizes (or discourages) the move's usage on a specific target. A positive TBS indicates the move is better used on the user or its allies, while a negative TBS indicates the move is better used on enemies. - A move's **target benefit score (TBS)** incentivizes (or discourages) the move's usage on a specific target. A positive TBS indicates the move is better used on the user or its allies, while a negative TBS indicates the move is better used on enemies.
- **The total benefit score (UBS + TBS) of a move should never be 0.** The move selection algorithm assumes the move's benefit score is unimplemented if the total score is 0 and penalizes the move's usage as a result. With status moves especially, it's important to have some form of implementation among the move's attributes to avoid this scenario. - **The total benefit score (UBS + TBS) of a move should never be 0.** The move selection algorithm assumes the move's benefit score is unimplemented if the total score is 0 and penalizes the move's usage as a result. With status moves especially, it's important to have some form of implementation among the move's attributes to avoid this scenario.
- **Score functions that use formulas should include comments.** If your attribute requires complex logic or formulas to calculate benefit scores, please add comments to explain how the logic works and its intended effect on the enemy's decision making. - **Score functions that use formulas should include comments.** If your attribute requires complex logic or formulas to calculate benefit scores, please add comments to explain how the logic works and its intended effect on the enemy's decision making.

View File

@ -23,15 +23,6 @@ body {
} }
} }
#links {
width: 90%;
text-align: center;
position: fixed;
bottom: 0;
display: flex;
justify-content: space-around;
}
#app { #app {
display: flex; display: flex;
justify-content: center; justify-content: center;
@ -93,7 +84,7 @@ input:-internal-autofill-selected {
@media (orientation: landscape) { @media (orientation: landscape) {
#touchControls { #touchControls {
--controls-size: 20vh; --controls-size: 20vh;
--text-shadow-size: 1.3vh; --text-shadow-size: 1.3vh;
--small-button-offset: 4vh; --small-button-offset: 4vh;
} }

View File

@ -39,7 +39,6 @@
</style> </style>
<link rel="stylesheet" type="text/css" href="./index.css" /> <link rel="stylesheet" type="text/css" href="./index.css" />
<link rel="manifest" href="./manifest.webmanifest"> <link rel="manifest" href="./manifest.webmanifest">
<script type="text/javascript" src="https://app.termly.io/resource-blocker/c5dbfa2f-9723-4c0f-a84b-2895124e851f?autoBlock=on"></script>
<script> <script>
if ("serviceWorker" in navigator) { if ("serviceWorker" in navigator) {
window.addEventListener("load", function () { window.addEventListener("load", function () {
@ -144,13 +143,6 @@
</div> </div>
</div> </div>
<div id="tnc-links">
<a href="#" class="termly-display-preferences" style="display: none;" target="_blank" rel="noreferrer noopener">Consent Preferences</a>
<a href="https://app.termly.io/policy-viewer/policy.html?policyUUID=bc96778b-3f04-4d25-bafc-0deba53e8bec" target="_blank" rel="noreferrer noopener">Privacy Policy</a>
<a href="https://app.termly.io/policy-viewer/policy.html?policyUUID=8b523c05-7ec2-4646-9534-5bd61b386e2a" target="_blank" rel="noreferrer noopener">Cookie Disclaimer</a>
<a href="https://app.termly.io/policy-viewer/policy.html?policyUUID=b01e092a-9721-477f-8356-45576702ff9e" target="_blank" rel="noreferrer noopener">Terms & Conditions</a>
<a href="https://app.termly.io/policy-viewer/policy.html?policyUUID=3b5d1928-3f5b-4ee1-b8df-2d6c276b0bcc" target="_blank" rel="noreferrer noopener">Acceptable Use Policy</a>
</div>
<script type="module" src="./src/main.ts"></script> <script type="module" src="./src/main.ts"></script>
<script src="./src/touch-controls.ts" type="module"></script> <script src="./src/touch-controls.ts" type="module"></script>
<script src="./src/debug.js" type="module"></script> <script src="./src/debug.js" type="module"></script>

View File

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 B

View File

@ -130,7 +130,7 @@ export default class BattleScene extends SceneBase {
public gameSpeed: integer = 1; public gameSpeed: integer = 1;
public damageNumbersMode: integer = 0; public damageNumbersMode: integer = 0;
public reroll: boolean = false; public reroll: boolean = false;
public shopCursorTarget: number = ShopCursorTarget.CHECK_TEAM; public shopCursorTarget: number = ShopCursorTarget.REWARDS;
public showMovesetFlyout: boolean = true; public showMovesetFlyout: boolean = true;
public showArenaFlyout: boolean = true; public showArenaFlyout: boolean = true;
public showTimeOfDayWidget: boolean = true; public showTimeOfDayWidget: boolean = true;
@ -841,12 +841,13 @@ export default class BattleScene extends SceneBase {
} }
addEnemyPokemon(species: PokemonSpecies, level: integer, trainerSlot: TrainerSlot, boss: boolean = false, dataSource?: PokemonData, postProcess?: (enemyPokemon: EnemyPokemon) => void): EnemyPokemon { addEnemyPokemon(species: PokemonSpecies, level: integer, trainerSlot: TrainerSlot, boss: boolean = false, dataSource?: PokemonData, postProcess?: (enemyPokemon: EnemyPokemon) => void): EnemyPokemon {
if (Overrides.OPP_LEVEL_OVERRIDE > 0) {
level = Overrides.OPP_LEVEL_OVERRIDE;
}
if (Overrides.OPP_SPECIES_OVERRIDE) { if (Overrides.OPP_SPECIES_OVERRIDE) {
species = getPokemonSpecies(Overrides.OPP_SPECIES_OVERRIDE); species = getPokemonSpecies(Overrides.OPP_SPECIES_OVERRIDE);
} // The fact that a Pokemon is a boss or not can change based on its Species and level
boss = this.getEncounterBossSegments(this.currentBattle.waveIndex, level, species) > 1;
if (Overrides.OPP_LEVEL_OVERRIDE !== 0) {
level = Overrides.OPP_LEVEL_OVERRIDE;
} }
const pokemon = new EnemyPokemon(this, species, level, trainerSlot, boss, dataSource); const pokemon = new EnemyPokemon(this, species, level, trainerSlot, boss, dataSource);
@ -973,6 +974,7 @@ export default class BattleScene extends SceneBase {
this.setSeed(Overrides.SEED_OVERRIDE || Utils.randomString(24)); this.setSeed(Overrides.SEED_OVERRIDE || Utils.randomString(24));
console.log("Seed:", this.seed); console.log("Seed:", this.seed);
this.resetSeed(); // Properly resets RNG after saving and quitting a session
this.disableMenu = false; this.disableMenu = false;
@ -1327,6 +1329,13 @@ export default class BattleScene extends SceneBase {
} }
getEncounterBossSegments(waveIndex: integer, level: integer, species?: PokemonSpecies, forceBoss: boolean = false): integer { getEncounterBossSegments(waveIndex: integer, level: integer, species?: PokemonSpecies, forceBoss: boolean = false): integer {
if (Overrides.OPP_HEALTH_SEGMENTS_OVERRIDE > 1) {
return Overrides.OPP_HEALTH_SEGMENTS_OVERRIDE;
} else if (Overrides.OPP_HEALTH_SEGMENTS_OVERRIDE === 1) {
// The rest of the code expects to be returned 0 and not 1 if the enemy is not a boss
return 0;
}
if (this.gameMode.isDaily && this.gameMode.isWaveFinal(waveIndex)) { if (this.gameMode.isDaily && this.gameMode.isWaveFinal(waveIndex)) {
return 5; return 5;
} }
@ -2733,6 +2742,29 @@ export default class BattleScene extends SceneBase {
(window as any).gameInfo = gameInfo; (window as any).gameInfo = gameInfo;
} }
/**
* This function retrieves the sprite and audio keys for active Pokemon.
* Active Pokemon include both enemy and player Pokemon of the current wave.
* Note: Questions on garbage collection go to @frutescens
* @returns a string array of active sprite and audio keys that should not be deleted
*/
getActiveKeys(): string[] {
const keys: string[] = [];
const playerParty = this.getParty();
playerParty.forEach(p => {
keys.push("pkmn__" + p.species.getSpriteId(p.gender === Gender.FEMALE, p.species.formIndex, p.shiny, p.variant));
keys.push("pkmn__" + p.species.getSpriteId(p.gender === Gender.FEMALE, p.species.formIndex, p.shiny, p.variant, true));
keys.push("cry/" + p.species.getCryKey(p.species.formIndex));
});
// 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));
});
return keys;
}
/** /**
* Initialized the 2nd phase of the final boss (e.g. form-change for Eternatus) * Initialized the 2nd phase of the final boss (e.g. form-change for Eternatus)
* @param pokemon The (enemy) pokemon * @param pokemon The (enemy) pokemon

File diff suppressed because it is too large Load Diff

View File

@ -7,17 +7,17 @@ import Pokemon, { HitResult, PokemonMove } from "../field/pokemon";
import { StatusEffect } from "./status-effect"; import { StatusEffect } from "./status-effect";
import { BattlerIndex } from "../battle"; import { BattlerIndex } from "../battle";
import { BlockNonDirectDamageAbAttr, ChangeMovePriorityAbAttr, ProtectStatAbAttr, applyAbAttrs } from "./ability"; import { BlockNonDirectDamageAbAttr, ChangeMovePriorityAbAttr, ProtectStatAbAttr, applyAbAttrs } from "./ability";
import { BattleStat } from "./battle-stat"; import { Stat } from "#enums/stat";
import { CommonAnim, CommonBattleAnim } from "./battle-anims"; import { CommonAnim, CommonBattleAnim } from "./battle-anims";
import i18next from "i18next"; import i18next from "i18next";
import { Abilities } from "#enums/abilities"; import { Abilities } from "#enums/abilities";
import { ArenaTagType } from "#enums/arena-tag-type"; import { ArenaTagType } from "#enums/arena-tag-type";
import { BattlerTagType } from "#enums/battler-tag-type"; import { BattlerTagType } from "#enums/battler-tag-type";
import { Moves } from "#enums/moves"; import { Moves } from "#enums/moves";
import { MoveEffectPhase } from "#app/phases/move-effect-phase.js"; import { MoveEffectPhase } from "#app/phases/move-effect-phase";
import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase.js"; import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase";
import { ShowAbilityPhase } from "#app/phases/show-ability-phase.js"; import { ShowAbilityPhase } from "#app/phases/show-ability-phase";
import { StatChangePhase } from "#app/phases/stat-change-phase.js"; import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
export enum ArenaTagSide { export enum ArenaTagSide {
BOTH, BOTH,
@ -786,8 +786,8 @@ class StickyWebTag extends ArenaTrapTag {
applyAbAttrs(ProtectStatAbAttr, pokemon, cancelled); applyAbAttrs(ProtectStatAbAttr, pokemon, cancelled);
if (!cancelled.value) { if (!cancelled.value) {
pokemon.scene.queueMessage(i18next.t("arenaTag:stickyWebActivateTrap", { pokemonName: pokemon.getNameToRender() })); pokemon.scene.queueMessage(i18next.t("arenaTag:stickyWebActivateTrap", { pokemonName: pokemon.getNameToRender() }));
const statLevels = new Utils.NumberHolder(-1); const stages = new Utils.NumberHolder(-1);
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), false, [BattleStat.SPD], statLevels.value)); pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), false, [ Stat.SPD ], stages.value));
} }
} }
@ -875,7 +875,7 @@ class TailwindTag extends ArenaTag {
// Raise attack by one stage if party member has WIND_RIDER ability // Raise attack by one stage if party member has WIND_RIDER ability
if (pokemon.hasAbility(Abilities.WIND_RIDER)) { if (pokemon.hasAbility(Abilities.WIND_RIDER)) {
pokemon.scene.unshiftPhase(new ShowAbilityPhase(pokemon.scene, pokemon.getBattlerIndex())); pokemon.scene.unshiftPhase(new ShowAbilityPhase(pokemon.scene, pokemon.getBattlerIndex()));
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [BattleStat.ATK], 1, true)); pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ Stat.ATK ], 1, true));
} }
} }
} }

View File

@ -1,71 +0,0 @@
import i18next, { ParseKeys } from "i18next";
export enum BattleStat {
ATK,
DEF,
SPATK,
SPDEF,
SPD,
ACC,
EVA,
RAND,
HP
}
export function getBattleStatName(stat: BattleStat) {
switch (stat) {
case BattleStat.ATK:
return i18next.t("pokemonInfo:Stat.ATK");
case BattleStat.DEF:
return i18next.t("pokemonInfo:Stat.DEF");
case BattleStat.SPATK:
return i18next.t("pokemonInfo:Stat.SPATK");
case BattleStat.SPDEF:
return i18next.t("pokemonInfo:Stat.SPDEF");
case BattleStat.SPD:
return i18next.t("pokemonInfo:Stat.SPD");
case BattleStat.ACC:
return i18next.t("pokemonInfo:Stat.ACC");
case BattleStat.EVA:
return i18next.t("pokemonInfo:Stat.EVA");
case BattleStat.HP:
return i18next.t("pokemonInfo:Stat.HPStat");
default:
return "???";
}
}
export function getBattleStatLevelChangeDescription(pokemonNameWithAffix: string, stats: string, levels: integer, up: boolean, count: number = 1) {
const stringKey = (() => {
if (up) {
switch (levels) {
case 1:
return "battle:statRose";
case 2:
return "battle:statSharplyRose";
case 3:
case 4:
case 5:
case 6:
return "battle:statRoseDrastically";
default:
return "battle:statWontGoAnyHigher";
}
} else {
switch (levels) {
case 1:
return "battle:statFell";
case 2:
return "battle:statHarshlyFell";
case 3:
case 4:
case 5:
case 6:
return "battle:statSeverelyFell";
default:
return "battle:statWontGoAnyLower";
}
}
})();
return i18next.t(stringKey as ParseKeys, { pokemonNameWithAffix, stats, count });
}

View File

@ -1,7 +1,6 @@
import { ChargeAnim, CommonAnim, CommonBattleAnim, MoveChargeAnim } from "./battle-anims"; import { ChargeAnim, CommonAnim, CommonBattleAnim, MoveChargeAnim } from "./battle-anims";
import { getPokemonNameWithAffix } from "../messages"; import { getPokemonNameWithAffix } from "../messages";
import Pokemon, { MoveResult, HitResult } from "../field/pokemon"; import Pokemon, { MoveResult, HitResult } from "../field/pokemon";
import { Stat, getStatName } from "./pokemon-stat";
import { StatusEffect } from "./status-effect"; import { StatusEffect } from "./status-effect";
import * as Utils from "../utils"; import * as Utils from "../utils";
import { ChargeAttr, MoveFlags, allMoves } from "./move"; import { ChargeAttr, MoveFlags, allMoves } from "./move";
@ -9,20 +8,20 @@ import { Type } from "./type";
import { BlockNonDirectDamageAbAttr, FlinchEffectAbAttr, ReverseDrainAbAttr, applyAbAttrs } from "./ability"; import { BlockNonDirectDamageAbAttr, FlinchEffectAbAttr, ReverseDrainAbAttr, applyAbAttrs } from "./ability";
import { TerrainType } from "./terrain"; import { TerrainType } from "./terrain";
import { WeatherType } from "./weather"; import { WeatherType } from "./weather";
import { BattleStat } from "./battle-stat";
import { allAbilities } from "./ability"; import { allAbilities } from "./ability";
import { SpeciesFormChangeManualTrigger } from "./pokemon-forms"; import { SpeciesFormChangeManualTrigger } from "./pokemon-forms";
import { Abilities } from "#enums/abilities"; import { Abilities } from "#enums/abilities";
import { BattlerTagType } from "#enums/battler-tag-type"; import { BattlerTagType } from "#enums/battler-tag-type";
import { Moves } from "#enums/moves"; import { Moves } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import i18next from "#app/plugins/i18n.js"; import i18next from "#app/plugins/i18n";
import { CommonAnimPhase } from "#app/phases/common-anim-phase.js"; import { Stat, type BattleStat, type EffectiveStat, EFFECTIVE_STATS, getStatKey } from "#app/enums/stat";
import { MoveEffectPhase } from "#app/phases/move-effect-phase.js"; import { CommonAnimPhase } from "#app/phases/common-anim-phase";
import { MovePhase } from "#app/phases/move-phase.js"; import { MoveEffectPhase } from "#app/phases/move-effect-phase";
import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase.js"; import { MovePhase } from "#app/phases/move-phase";
import { ShowAbilityPhase } from "#app/phases/show-ability-phase.js"; import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase";
import { StatChangePhase, StatChangeCallback } from "#app/phases/stat-change-phase.js"; import { ShowAbilityPhase } from "#app/phases/show-ability-phase";
import { StatStageChangePhase, StatStageChangeCallback } from "#app/phases/stat-stage-change-phase";
export enum BattlerTagLapseType { export enum BattlerTagLapseType {
FAINT, FAINT,
@ -40,13 +39,15 @@ export class BattlerTag {
public turnCount: number; public turnCount: number;
public sourceMove: Moves; public sourceMove: Moves;
public sourceId?: number; public sourceId?: number;
public isBatonPassable: boolean;
constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType | BattlerTagLapseType[], turnCount: number, sourceMove?: Moves, sourceId?: number) { constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType | BattlerTagLapseType[], turnCount: number, sourceMove?: Moves, sourceId?: number, isBatonPassable: boolean = false) {
this.tagType = tagType; this.tagType = tagType;
this.lapseTypes = Array.isArray(lapseType) ? lapseType : [ lapseType ]; this.lapseTypes = Array.isArray(lapseType) ? lapseType : [ lapseType ];
this.turnCount = turnCount; this.turnCount = turnCount;
this.sourceMove = sourceMove!; // TODO: is this bang correct? this.sourceMove = sourceMove!; // TODO: is this bang correct?
this.sourceId = sourceId; this.sourceId = sourceId;
this.isBatonPassable = isBatonPassable;
} }
canAdd(pokemon: Pokemon): boolean { canAdd(pokemon: Pokemon): boolean {
@ -207,7 +208,7 @@ export class ShellTrapTag extends BattlerTag {
export class TrappedTag extends BattlerTag { export class TrappedTag extends BattlerTag {
constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType, turnCount: number, sourceMove: Moves, sourceId: number) { constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType, turnCount: number, sourceMove: Moves, sourceId: number) {
super(tagType, lapseType, turnCount, sourceMove, sourceId); super(tagType, lapseType, turnCount, sourceMove, sourceId, true);
} }
canAdd(pokemon: Pokemon): boolean { canAdd(pokemon: Pokemon): boolean {
@ -327,7 +328,7 @@ export class InterruptedTag extends BattlerTag {
*/ */
export class ConfusedTag extends BattlerTag { export class ConfusedTag extends BattlerTag {
constructor(turnCount: number, sourceMove: Moves) { constructor(turnCount: number, sourceMove: Moves) {
super(BattlerTagType.CONFUSED, BattlerTagLapseType.MOVE, turnCount, sourceMove); super(BattlerTagType.CONFUSED, BattlerTagLapseType.MOVE, turnCount, sourceMove, undefined, true);
} }
canAdd(pokemon: Pokemon): boolean { canAdd(pokemon: Pokemon): boolean {
@ -362,8 +363,8 @@ export class ConfusedTag extends BattlerTag {
// 1/3 chance of hitting self with a 40 base power move // 1/3 chance of hitting self with a 40 base power move
if (pokemon.randSeedInt(3) === 0) { if (pokemon.randSeedInt(3) === 0) {
const atk = pokemon.getBattleStat(Stat.ATK); const atk = pokemon.getEffectiveStat(Stat.ATK);
const def = pokemon.getBattleStat(Stat.DEF); const def = pokemon.getEffectiveStat(Stat.DEF);
const damage = Utils.toDmgValue(((((2 * pokemon.level / 5 + 2) * 40 * atk / def) / 50) + 2) * (pokemon.randSeedInt(15, 85) / 100)); const damage = Utils.toDmgValue(((((2 * pokemon.level / 5 + 2) * 40 * atk / def) / 50) + 2) * (pokemon.randSeedInt(15, 85) / 100));
pokemon.scene.queueMessage(i18next.t("battlerTags:confusedLapseHurtItself")); pokemon.scene.queueMessage(i18next.t("battlerTags:confusedLapseHurtItself"));
pokemon.damageAndUpdate(damage); pokemon.damageAndUpdate(damage);
@ -387,7 +388,7 @@ export class ConfusedTag extends BattlerTag {
*/ */
export class DestinyBondTag extends BattlerTag { export class DestinyBondTag extends BattlerTag {
constructor(sourceMove: Moves, sourceId: number) { constructor(sourceMove: Moves, sourceId: number) {
super(BattlerTagType.DESTINY_BOND, BattlerTagLapseType.PRE_MOVE, 1, sourceMove, sourceId); super(BattlerTagType.DESTINY_BOND, BattlerTagLapseType.PRE_MOVE, 1, sourceMove, sourceId, true);
} }
/** /**
@ -506,7 +507,7 @@ export class SeedTag extends BattlerTag {
private sourceIndex: number; private sourceIndex: number;
constructor(sourceId: number) { constructor(sourceId: number) {
super(BattlerTagType.SEEDED, BattlerTagLapseType.TURN_END, 1, Moves.LEECH_SEED, sourceId); super(BattlerTagType.SEEDED, BattlerTagLapseType.TURN_END, 1, Moves.LEECH_SEED, sourceId, true);
} }
/** /**
@ -767,7 +768,7 @@ export class OctolockTag extends TrappedTag {
const shouldLapse = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType); const shouldLapse = lapseType !== BattlerTagLapseType.CUSTOM || super.lapse(pokemon, lapseType);
if (shouldLapse) { if (shouldLapse) {
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), false, [BattleStat.DEF, BattleStat.SPDEF], -1)); pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), false, [ Stat.DEF, Stat.SPDEF ], -1));
return true; return true;
} }
@ -777,7 +778,7 @@ export class OctolockTag extends TrappedTag {
export class AquaRingTag extends BattlerTag { export class AquaRingTag extends BattlerTag {
constructor() { constructor() {
super(BattlerTagType.AQUA_RING, BattlerTagLapseType.TURN_END, 1, Moves.AQUA_RING, undefined); super(BattlerTagType.AQUA_RING, BattlerTagLapseType.TURN_END, 1, Moves.AQUA_RING, undefined, true);
} }
onAdd(pokemon: Pokemon): void { onAdd(pokemon: Pokemon): void {
@ -809,7 +810,7 @@ export class AquaRingTag extends BattlerTag {
/** Tag used to allow moves that interact with {@link Moves.MINIMIZE} to function */ /** Tag used to allow moves that interact with {@link Moves.MINIMIZE} to function */
export class MinimizeTag extends BattlerTag { export class MinimizeTag extends BattlerTag {
constructor() { constructor() {
super(BattlerTagType.MINIMIZED, BattlerTagLapseType.TURN_END, 1, Moves.MINIMIZE, undefined); super(BattlerTagType.MINIMIZED, BattlerTagLapseType.TURN_END, 1, Moves.MINIMIZE);
} }
canAdd(pokemon: Pokemon): boolean { canAdd(pokemon: Pokemon): boolean {
@ -1093,7 +1094,7 @@ export class ContactDamageProtectedTag extends ProtectedTag {
} }
} }
export class ContactStatChangeProtectedTag extends ProtectedTag { export class ContactStatStageChangeProtectedTag extends ProtectedTag {
private stat: BattleStat; private stat: BattleStat;
private levels: number; private levels: number;
@ -1110,7 +1111,7 @@ export class ContactStatChangeProtectedTag extends ProtectedTag {
*/ */
loadTag(source: BattlerTag | any): void { loadTag(source: BattlerTag | any): void {
super.loadTag(source); super.loadTag(source);
this.stat = source.stat as BattleStat; this.stat = source.stat;
this.levels = source.levels; this.levels = source.levels;
} }
@ -1121,7 +1122,7 @@ export class ContactStatChangeProtectedTag extends ProtectedTag {
const effectPhase = pokemon.scene.getCurrentPhase(); const effectPhase = pokemon.scene.getCurrentPhase();
if (effectPhase instanceof MoveEffectPhase && effectPhase.move.getMove().hasFlag(MoveFlags.MAKES_CONTACT)) { if (effectPhase instanceof MoveEffectPhase && effectPhase.move.getMove().hasFlag(MoveFlags.MAKES_CONTACT)) {
const attacker = effectPhase.getPokemon(); const attacker = effectPhase.getPokemon();
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, attacker.getBattlerIndex(), true, [ this.stat ], this.levels)); pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, attacker.getBattlerIndex(), true, [ this.stat ], this.levels));
} }
} }
@ -1207,7 +1208,7 @@ export class SturdyTag extends BattlerTag {
export class PerishSongTag extends BattlerTag { export class PerishSongTag extends BattlerTag {
constructor(turnCount: number) { constructor(turnCount: number) {
super(BattlerTagType.PERISH_SONG, BattlerTagLapseType.TURN_END, turnCount, Moves.PERISH_SONG); super(BattlerTagType.PERISH_SONG, BattlerTagLapseType.TURN_END, turnCount, Moves.PERISH_SONG, undefined, true);
} }
canAdd(pokemon: Pokemon): boolean { canAdd(pokemon: Pokemon): boolean {
@ -1263,7 +1264,7 @@ export class AbilityBattlerTag extends BattlerTag {
public ability: Abilities; public ability: Abilities;
constructor(tagType: BattlerTagType, ability: Abilities, lapseType: BattlerTagLapseType, turnCount: number) { constructor(tagType: BattlerTagType, ability: Abilities, lapseType: BattlerTagLapseType, turnCount: number) {
super(tagType, lapseType, turnCount, undefined); super(tagType, lapseType, turnCount);
this.ability = ability; this.ability = ability;
} }
@ -1348,11 +1349,10 @@ export class HighestStatBoostTag extends AbilityBattlerTag {
onAdd(pokemon: Pokemon): void { onAdd(pokemon: Pokemon): void {
super.onAdd(pokemon); super.onAdd(pokemon);
const stats = [ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ]; let highestStat: EffectiveStat;
let highestStat: Stat; EFFECTIVE_STATS.map(s => pokemon.getEffectiveStat(s)).reduce((highestValue: number, value: number, i: number) => {
stats.map(s => pokemon.getBattleStat(s)).reduce((highestValue: number, value: number, i: number) => {
if (value > highestValue) { if (value > highestValue) {
highestStat = stats[i]; highestStat = EFFECTIVE_STATS[i];
return value; return value;
} }
return highestValue; return highestValue;
@ -1370,7 +1370,7 @@ export class HighestStatBoostTag extends AbilityBattlerTag {
break; break;
} }
pokemon.scene.queueMessage(i18next.t("battlerTags:highestStatBoostOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), statName: getStatName(highestStat) }), null, false, null, true); pokemon.scene.queueMessage(i18next.t("battlerTags:highestStatBoostOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), statName: i18next.t(getStatKey(highestStat)) }), null, false, null, true);
} }
onRemove(pokemon: Pokemon): void { onRemove(pokemon: Pokemon): void {
@ -1440,7 +1440,7 @@ export class TypeImmuneTag extends BattlerTag {
public immuneType: Type; public immuneType: Type;
constructor(tagType: BattlerTagType, sourceMove: Moves, immuneType: Type, length: number = 1) { constructor(tagType: BattlerTagType, sourceMove: Moves, immuneType: Type, length: number = 1) {
super(tagType, BattlerTagLapseType.TURN_END, length, sourceMove); super(tagType, BattlerTagLapseType.TURN_END, length, sourceMove, undefined, true);
this.immuneType = immuneType; this.immuneType = immuneType;
} }
@ -1504,7 +1504,7 @@ export class TypeBoostTag extends BattlerTag {
export class CritBoostTag extends BattlerTag { export class CritBoostTag extends BattlerTag {
constructor(tagType: BattlerTagType, sourceMove: Moves) { constructor(tagType: BattlerTagType, sourceMove: Moves) {
super(tagType, BattlerTagLapseType.TURN_END, 1, sourceMove); super(tagType, BattlerTagLapseType.TURN_END, 1, sourceMove, undefined, true);
} }
onAdd(pokemon: Pokemon): void { onAdd(pokemon: Pokemon): void {
@ -1596,7 +1596,7 @@ export class CursedTag extends BattlerTag {
private sourceIndex: number; private sourceIndex: number;
constructor(sourceId: number) { constructor(sourceId: number) {
super(BattlerTagType.CURSED, BattlerTagLapseType.TURN_END, 1, Moves.CURSE, sourceId); super(BattlerTagType.CURSED, BattlerTagLapseType.TURN_END, 1, Moves.CURSE, sourceId, true);
} }
/** /**
@ -1714,25 +1714,25 @@ export class IceFaceBlockDamageTag extends FormBlockDamageTag {
*/ */
export class StockpilingTag extends BattlerTag { export class StockpilingTag extends BattlerTag {
public stockpiledCount: number = 0; public stockpiledCount: number = 0;
public statChangeCounts: { [BattleStat.DEF]: number; [BattleStat.SPDEF]: number } = { public statChangeCounts: { [Stat.DEF]: number; [Stat.SPDEF]: number } = {
[BattleStat.DEF]: 0, [Stat.DEF]: 0,
[BattleStat.SPDEF]: 0 [Stat.SPDEF]: 0
}; };
constructor(sourceMove: Moves = Moves.NONE) { constructor(sourceMove: Moves = Moves.NONE) {
super(BattlerTagType.STOCKPILING, BattlerTagLapseType.CUSTOM, 1, sourceMove); super(BattlerTagType.STOCKPILING, BattlerTagLapseType.CUSTOM, 1, sourceMove);
} }
private onStatsChanged: StatChangeCallback = (_, statsChanged, statChanges) => { private onStatStagesChanged: StatStageChangeCallback = (_, statsChanged, statChanges) => {
const defChange = statChanges[statsChanged.indexOf(BattleStat.DEF)] ?? 0; const defChange = statChanges[statsChanged.indexOf(Stat.DEF)] ?? 0;
const spDefChange = statChanges[statsChanged.indexOf(BattleStat.SPDEF)] ?? 0; const spDefChange = statChanges[statsChanged.indexOf(Stat.SPDEF)] ?? 0;
if (defChange) { if (defChange) {
this.statChangeCounts[BattleStat.DEF]++; this.statChangeCounts[Stat.DEF]++;
} }
if (spDefChange) { if (spDefChange) {
this.statChangeCounts[BattleStat.SPDEF]++; this.statChangeCounts[Stat.SPDEF]++;
} }
}; };
@ -1740,8 +1740,8 @@ export class StockpilingTag extends BattlerTag {
super.loadTag(source); super.loadTag(source);
this.stockpiledCount = source.stockpiledCount || 0; this.stockpiledCount = source.stockpiledCount || 0;
this.statChangeCounts = { this.statChangeCounts = {
[ BattleStat.DEF ]: source.statChangeCounts?.[ BattleStat.DEF ] ?? 0, [ Stat.DEF ]: source.statChangeCounts?.[ Stat.DEF ] ?? 0,
[ BattleStat.SPDEF ]: source.statChangeCounts?.[ BattleStat.SPDEF ] ?? 0, [ Stat.SPDEF ]: source.statChangeCounts?.[ Stat.SPDEF ] ?? 0,
}; };
} }
@ -1761,9 +1761,9 @@ export class StockpilingTag extends BattlerTag {
})); }));
// Attempt to increase DEF and SPDEF by one stage, keeping track of successful changes. // Attempt to increase DEF and SPDEF by one stage, keeping track of successful changes.
pokemon.scene.unshiftPhase(new StatChangePhase( pokemon.scene.unshiftPhase(new StatStageChangePhase(
pokemon.scene, pokemon.getBattlerIndex(), true, pokemon.scene, pokemon.getBattlerIndex(), true,
[BattleStat.SPDEF, BattleStat.DEF], 1, true, false, true, this.onStatsChanged [Stat.SPDEF, Stat.DEF], 1, true, false, true, this.onStatStagesChanged
)); ));
} }
} }
@ -1777,15 +1777,15 @@ export class StockpilingTag extends BattlerTag {
* one stage for each stack which had successfully changed that particular stat during onAdd. * one stage for each stack which had successfully changed that particular stat during onAdd.
*/ */
onRemove(pokemon: Pokemon): void { onRemove(pokemon: Pokemon): void {
const defChange = this.statChangeCounts[BattleStat.DEF]; const defChange = this.statChangeCounts[Stat.DEF];
const spDefChange = this.statChangeCounts[BattleStat.SPDEF]; const spDefChange = this.statChangeCounts[Stat.SPDEF];
if (defChange) { if (defChange) {
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [BattleStat.DEF], -defChange, true, false, true)); pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ Stat.DEF ], -defChange, true, false, true));
} }
if (spDefChange) { if (spDefChange) {
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [BattleStat.SPDEF], -spDefChange, true, false, true)); pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ Stat.SPDEF ], -spDefChange, true, false, true));
} }
} }
} }
@ -1927,11 +1927,11 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source
case BattlerTagType.SPIKY_SHIELD: case BattlerTagType.SPIKY_SHIELD:
return new ContactDamageProtectedTag(sourceMove, 8); return new ContactDamageProtectedTag(sourceMove, 8);
case BattlerTagType.KINGS_SHIELD: case BattlerTagType.KINGS_SHIELD:
return new ContactStatChangeProtectedTag(sourceMove, tagType, BattleStat.ATK, -1); return new ContactStatStageChangeProtectedTag(sourceMove, tagType, Stat.ATK, -1);
case BattlerTagType.OBSTRUCT: case BattlerTagType.OBSTRUCT:
return new ContactStatChangeProtectedTag(sourceMove, tagType, BattleStat.DEF, -2); return new ContactStatStageChangeProtectedTag(sourceMove, tagType, Stat.DEF, -2);
case BattlerTagType.SILK_TRAP: case BattlerTagType.SILK_TRAP:
return new ContactStatChangeProtectedTag(sourceMove, tagType, BattleStat.SPD, -1); return new ContactStatStageChangeProtectedTag(sourceMove, tagType, Stat.SPD, -1);
case BattlerTagType.BANEFUL_BUNKER: case BattlerTagType.BANEFUL_BUNKER:
return new ContactPoisonProtectedTag(sourceMove); return new ContactPoisonProtectedTag(sourceMove);
case BattlerTagType.BURNING_BULWARK: case BattlerTagType.BURNING_BULWARK:

View File

@ -1,14 +1,14 @@
import { getPokemonNameWithAffix } from "../messages"; import { getPokemonNameWithAffix } from "../messages";
import Pokemon, { HitResult } from "../field/pokemon"; import Pokemon, { HitResult } from "../field/pokemon";
import { BattleStat } from "./battle-stat";
import { getStatusEffectHealText } from "./status-effect"; import { getStatusEffectHealText } from "./status-effect";
import * as Utils from "../utils"; import * as Utils from "../utils";
import { DoubleBerryEffectAbAttr, ReduceBerryUseThresholdAbAttr, applyAbAttrs } from "./ability"; import { DoubleBerryEffectAbAttr, ReduceBerryUseThresholdAbAttr, applyAbAttrs } from "./ability";
import i18next from "i18next"; import i18next from "i18next";
import { BattlerTagType } from "#enums/battler-tag-type"; import { BattlerTagType } from "#enums/battler-tag-type";
import { BerryType } from "#enums/berry-type"; import { BerryType } from "#enums/berry-type";
import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase.js"; import { Stat, type BattleStat } from "#app/enums/stat";
import { StatChangePhase } from "#app/phases/stat-change-phase.js"; import { PokemonHealPhase } from "#app/phases/pokemon-heal-phase";
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
export function getBerryName(berryType: BerryType): string { export function getBerryName(berryType: BerryType): string {
return i18next.t(`berry:${BerryType[berryType]}.name`); return i18next.t(`berry:${BerryType[berryType]}.name`);
@ -35,9 +35,10 @@ export function getBerryPredicate(berryType: BerryType): BerryPredicate {
case BerryType.SALAC: case BerryType.SALAC:
return (pokemon: Pokemon) => { return (pokemon: Pokemon) => {
const threshold = new Utils.NumberHolder(0.25); const threshold = new Utils.NumberHolder(0.25);
const battleStat = (berryType - BerryType.LIECHI) as BattleStat; // Offset BerryType such that LIECHI -> Stat.ATK = 1, GANLON -> Stat.DEF = 2, so on and so forth
const stat: BattleStat = berryType - BerryType.ENIGMA;
applyAbAttrs(ReduceBerryUseThresholdAbAttr, pokemon, null, false, threshold); applyAbAttrs(ReduceBerryUseThresholdAbAttr, pokemon, null, false, threshold);
return pokemon.getHpRatio() < threshold.value && pokemon.summonData.battleStats[battleStat] < 6; return pokemon.getHpRatio() < threshold.value && pokemon.getStatStage(stat) < 6;
}; };
case BerryType.LANSAT: case BerryType.LANSAT:
return (pokemon: Pokemon) => { return (pokemon: Pokemon) => {
@ -95,10 +96,11 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc {
if (pokemon.battleData) { if (pokemon.battleData) {
pokemon.battleData.berriesEaten.push(berryType); pokemon.battleData.berriesEaten.push(berryType);
} }
const battleStat = (berryType - BerryType.LIECHI) as BattleStat; // Offset BerryType such that LIECHI -> Stat.ATK = 1, GANLON -> Stat.DEF = 2, so on and so forth
const statLevels = new Utils.NumberHolder(1); const stat: BattleStat = berryType - BerryType.ENIGMA;
applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, false, statLevels); const statStages = new Utils.NumberHolder(1);
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ battleStat ], statLevels.value)); applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, false, statStages);
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ stat ], statStages.value));
}; };
case BerryType.LANSAT: case BerryType.LANSAT:
return (pokemon: Pokemon) => { return (pokemon: Pokemon) => {
@ -112,9 +114,10 @@ export function getBerryEffectFunc(berryType: BerryType): BerryEffectFunc {
if (pokemon.battleData) { if (pokemon.battleData) {
pokemon.battleData.berriesEaten.push(berryType); pokemon.battleData.berriesEaten.push(berryType);
} }
const statLevels = new Utils.NumberHolder(2); const randStat = Utils.randSeedInt(Stat.SPD, Stat.ATK);
applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, false, statLevels); const stages = new Utils.NumberHolder(2);
pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ BattleStat.RAND ], statLevels.value)); applyAbAttrs(DoubleBerryEffectAbAttr, pokemon, null, false, stages);
pokemon.scene.unshiftPhase(new StatStageChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ randStat ], stages.value));
}; };
case BerryType.LEPPA: case BerryType.LEPPA:
return (pokemon: Pokemon) => { return (pokemon: Pokemon) => {

View File

@ -1,6 +1,6 @@
import { Type } from "./type"; import { Type } from "./type";
import * as Utils from "../utils"; import * as Utils from "../utils";
import {pokemonEvolutions, SpeciesFormEvolution} from "./pokemon-evolutions"; import { pokemonEvolutions, SpeciesFormEvolution } from "./pokemon-evolutions";
import i18next from "i18next"; import i18next from "i18next";
import { Biome } from "#enums/biome"; import { Biome } from "#enums/biome";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
@ -46,7 +46,7 @@ export const biomeLinks: BiomeLinks = {
[Biome.SEABED]: [ Biome.CAVE, [ Biome.VOLCANO, 3 ] ], [Biome.SEABED]: [ Biome.CAVE, [ Biome.VOLCANO, 3 ] ],
[Biome.MOUNTAIN]: [ Biome.VOLCANO, [ Biome.WASTELAND, 2 ], [ Biome.SPACE, 3 ] ], [Biome.MOUNTAIN]: [ Biome.VOLCANO, [ Biome.WASTELAND, 2 ], [ Biome.SPACE, 3 ] ],
[Biome.BADLANDS]: [ Biome.DESERT, Biome.MOUNTAIN ], [Biome.BADLANDS]: [ Biome.DESERT, Biome.MOUNTAIN ],
[Biome.CAVE]: [ Biome.BADLANDS, Biome.LAKE [ Biome.LABORATORY, 2 ] ], [Biome.CAVE]: [ Biome.BADLANDS, Biome.LAKE, [ Biome.LABORATORY, 2 ] ],
[Biome.DESERT]: [ Biome.RUINS, [ Biome.CONSTRUCTION_SITE, 2 ] ], [Biome.DESERT]: [ Biome.RUINS, [ Biome.CONSTRUCTION_SITE, 2 ] ],
[Biome.ICE_CAVE]: Biome.SNOWY_FOREST, [Biome.ICE_CAVE]: Biome.SNOWY_FOREST,
[Biome.MEADOW]: [ Biome.PLAINS, Biome.FAIRY_CAVE ], [Biome.MEADOW]: [ Biome.PLAINS, Biome.FAIRY_CAVE ],

View File

@ -13,7 +13,6 @@ import { TrainerType } from "#enums/trainer-type";
import { Nature } from "./nature"; import { Nature } from "./nature";
import { Moves } from "#app/enums/moves.js"; import { Moves } from "#app/enums/moves.js";
import { TypeColor, TypeShadow } from "#app/enums/color.js"; import { TypeColor, TypeShadow } from "#app/enums/color.js";
import { Gender } from "./gender";
import { pokemonEvolutions } from "./pokemon-evolutions"; import { pokemonEvolutions } from "./pokemon-evolutions";
import { pokemonFormChanges } from "./pokemon-forms"; import { pokemonFormChanges } from "./pokemon-forms";
@ -659,7 +658,6 @@ export class FreshStartChallenge extends Challenge {
pokemon.luck = 0; // No luck pokemon.luck = 0; // No luck
pokemon.shiny = false; // Not shiny pokemon.shiny = false; // Not shiny
pokemon.variant = 0; // Not shiny pokemon.variant = 0; // Not shiny
pokemon.gender = Gender.MALE; // Starters default to male
pokemon.formIndex = 0; // Froakie should be base form pokemon.formIndex = 0; // Froakie should be base form
pokemon.ivs = [10, 10, 10, 10, 10, 10]; // Default IVs of 10 for all stats pokemon.ivs = [10, 10, 10, 10, 10, 10]; // Default IVs of 10 for all stats
return true; return true;

View File

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

View File

@ -139,46 +139,57 @@ export class Egg {
//// ////
constructor(eggOptions?: IEggOptions) { constructor(eggOptions?: IEggOptions) {
//if (eggOptions.tier && eggOptions.species) throw Error("Error egg can't have species and tier as option. only choose one of them.") const generateEggProperties = (eggOptions?: IEggOptions) => {
//if (eggOptions.tier && eggOptions.species) throw Error("Error egg can't have species and tier as option. only choose one of them.")
this._sourceType = eggOptions?.sourceType!; // TODO: is this bang correct? this._sourceType = eggOptions?.sourceType!; // TODO: is this bang correct?
// Ensure _sourceType is defined before invoking rollEggTier(), as it is referenced // Ensure _sourceType is defined before invoking rollEggTier(), as it is referenced
this._tier = eggOptions?.tier ?? (Overrides.EGG_TIER_OVERRIDE ?? this.rollEggTier()); this._tier = eggOptions?.tier ?? (Overrides.EGG_TIER_OVERRIDE ?? this.rollEggTier());
// If egg was pulled, check if egg pity needs to override the egg tier // If egg was pulled, check if egg pity needs to override the egg tier
if (eggOptions?.pulled) { if (eggOptions?.pulled) {
// Needs this._tier and this._sourceType to work // Needs this._tier and this._sourceType to work
this.checkForPityTierOverrides(eggOptions.scene!); // TODO: is this bang correct? this.checkForPityTierOverrides(eggOptions.scene!); // TODO: is this bang correct?
} }
this._id = eggOptions?.id ?? Utils.randInt(EGG_SEED, EGG_SEED * this._tier); this._id = eggOptions?.id ?? Utils.randInt(EGG_SEED, EGG_SEED * this._tier);
this._sourceType = eggOptions?.sourceType ?? undefined; this._sourceType = eggOptions?.sourceType ?? undefined;
this._hatchWaves = eggOptions?.hatchWaves ?? this.getEggTierDefaultHatchWaves(); this._hatchWaves = eggOptions?.hatchWaves ?? this.getEggTierDefaultHatchWaves();
this._timestamp = eggOptions?.timestamp ?? new Date().getTime(); this._timestamp = eggOptions?.timestamp ?? new Date().getTime();
// First roll shiny and variant so we can filter if species with an variant exist // First roll shiny and variant so we can filter if species with an variant exist
this._isShiny = eggOptions?.isShiny ?? (Overrides.EGG_SHINY_OVERRIDE || this.rollShiny()); this._isShiny = eggOptions?.isShiny ?? (Overrides.EGG_SHINY_OVERRIDE || this.rollShiny());
this._variantTier = eggOptions?.variantTier ?? (Overrides.EGG_VARIANT_OVERRIDE ?? this.rollVariant()); this._variantTier = eggOptions?.variantTier ?? (Overrides.EGG_VARIANT_OVERRIDE ?? this.rollVariant());
this._species = eggOptions?.species ?? this.rollSpecies(eggOptions!.scene!)!; // TODO: Are those bangs correct? this._species = eggOptions?.species ?? this.rollSpecies(eggOptions!.scene!)!; // TODO: Are those bangs correct?
this._overrideHiddenAbility = eggOptions?.overrideHiddenAbility ?? false; this._overrideHiddenAbility = eggOptions?.overrideHiddenAbility ?? false;
// Override egg tier and hatchwaves if species was given // Override egg tier and hatchwaves if species was given
if (eggOptions?.species) { if (eggOptions?.species) {
this._tier = this.getEggTierFromSpeciesStarterValue(); this._tier = this.getEggTierFromSpeciesStarterValue();
this._hatchWaves = eggOptions.hatchWaves ?? this.getEggTierDefaultHatchWaves(); this._hatchWaves = eggOptions.hatchWaves ?? this.getEggTierDefaultHatchWaves();
} }
// If species has no variant, set variantTier to common. This needs to // If species has no variant, set variantTier to common. This needs to
// be done because species with no variants get filtered at rollSpecies but if the // be done because species with no variants get filtered at rollSpecies but if the
// species is set via options or the legendary gacha pokemon gets choosen the check never happens // species is set via options or the legendary gacha pokemon gets choosen the check never happens
if (this._species && !getPokemonSpecies(this._species).hasVariants()) { if (this._species && !getPokemonSpecies(this._species).hasVariants()) {
this._variantTier = VariantTier.COMMON; this._variantTier = VariantTier.COMMON;
} }
// Needs this._tier so it needs to be generated afer the tier override if bought from same species // Needs this._tier so it needs to be generated afer the tier override if bought from same species
this._eggMoveIndex = eggOptions?.eggMoveIndex ?? this.rollEggMoveIndex(); this._eggMoveIndex = eggOptions?.eggMoveIndex ?? this.rollEggMoveIndex();
if (eggOptions?.pulled) { if (eggOptions?.pulled) {
this.increasePullStatistic(eggOptions.scene!); // TODO: is this bang correct? this.increasePullStatistic(eggOptions.scene!); // TODO: is this bang correct?
this.addEggToGameData(eggOptions.scene!); // TODO: is this bang correct? this.addEggToGameData(eggOptions.scene!); // TODO: is this bang correct?
}
};
if (eggOptions?.scene) {
const seedOverride = Utils.randomString(24);
eggOptions?.scene.executeWithSeedOffset(() => {
generateEggProperties(eggOptions);
}, 0, seedOverride);
} else { // For legacy eggs without scene
generateEggProperties(eggOptions);
} }
} }
@ -200,37 +211,46 @@ export class Egg {
// Generates a PlayerPokemon from an egg // Generates a PlayerPokemon from an egg
public generatePlayerPokemon(scene: BattleScene): PlayerPokemon { public generatePlayerPokemon(scene: BattleScene): PlayerPokemon {
// Legacy egg wants to hatch. Generate missing properties let ret: PlayerPokemon;
if (!this._species) {
this._isShiny = this.rollShiny();
this._species = this.rollSpecies(scene!)!; // TODO: are these bangs correct?
}
let pokemonSpecies = getPokemonSpecies(this._species); const generatePlayerPokemonHelper = (scene: BattleScene) => {
// Special condition to have Phione eggs also have a chance of generating Manaphy // Legacy egg wants to hatch. Generate missing properties
if (this._species === Species.PHIONE) { if (!this._species) {
pokemonSpecies = getPokemonSpecies(Utils.randSeedInt(MANAPHY_EGG_MANAPHY_RATE) ? Species.PHIONE : Species.MANAPHY); this._isShiny = this.rollShiny();
} this._species = this.rollSpecies(scene!)!; // TODO: are these bangs correct?
}
// Sets the hidden ability if a hidden ability exists and let pokemonSpecies = getPokemonSpecies(this._species);
// the override is set or the egg hits the chance // Special condition to have Phione eggs also have a chance of generating Manaphy
let abilityIndex: number | undefined = undefined; if (this._species === Species.PHIONE) {
const sameSpeciesEggHACheck = (this._sourceType === EggSourceType.SAME_SPECIES_EGG && !Utils.randSeedInt(SAME_SPECIES_EGG_HA_RATE)); pokemonSpecies = getPokemonSpecies(Utils.randSeedInt(MANAPHY_EGG_MANAPHY_RATE) ? Species.PHIONE : Species.MANAPHY);
const gachaEggHACheck = (!(this._sourceType === EggSourceType.SAME_SPECIES_EGG) && !Utils.randSeedInt(GACHA_EGG_HA_RATE)); }
if (pokemonSpecies.abilityHidden && (this._overrideHiddenAbility || sameSpeciesEggHACheck || gachaEggHACheck)) {
abilityIndex = 2;
}
// This function has way to many optional parameters // Sets the hidden ability if a hidden ability exists and
const ret: PlayerPokemon = scene.addPlayerPokemon(pokemonSpecies, 1, abilityIndex, undefined, undefined, false); // the override is set or the egg hits the chance
ret.shiny = this._isShiny; let abilityIndex: number | undefined = undefined;
ret.variant = this._variantTier; const sameSpeciesEggHACheck = (this._sourceType === EggSourceType.SAME_SPECIES_EGG && !Utils.randSeedInt(SAME_SPECIES_EGG_HA_RATE));
const gachaEggHACheck = (!(this._sourceType === EggSourceType.SAME_SPECIES_EGG) && !Utils.randSeedInt(GACHA_EGG_HA_RATE));
if (pokemonSpecies.abilityHidden && (this._overrideHiddenAbility || sameSpeciesEggHACheck || gachaEggHACheck)) {
abilityIndex = 2;
}
const secondaryIvs = Utils.getIvsFromId(Utils.randSeedInt(4294967295)); // This function has way to many optional parameters
ret = scene.addPlayerPokemon(pokemonSpecies, 1, abilityIndex, undefined, undefined, false);
ret.shiny = this._isShiny;
ret.variant = this._variantTier;
for (let s = 0; s < ret.ivs.length; s++) { const secondaryIvs = Utils.getIvsFromId(Utils.randSeedInt(4294967295));
ret.ivs[s] = Math.max(ret.ivs[s], secondaryIvs[s]);
} for (let s = 0; s < ret.ivs.length; s++) {
ret.ivs[s] = Math.max(ret.ivs[s], secondaryIvs[s]);
}
};
ret = ret!; // Tell TS compiler it's defined now
scene.executeWithSeedOffset(() => {
generatePlayerPokemonHelper(scene);
}, this._id, EGG_SEED.toString());
return ret; return ret;
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,9 @@
import { Stat, getStatName } from "./pokemon-stat";
import * as Utils from "../utils"; import * as Utils from "../utils";
import { TextStyle, getBBCodeFrag } from "../ui/text"; import { TextStyle, getBBCodeFrag } from "../ui/text";
import { Nature } from "#enums/nature"; import { Nature } from "#enums/nature";
import { UiTheme } from "#enums/ui-theme"; import { UiTheme } from "#enums/ui-theme";
import i18next from "i18next"; import i18next from "i18next";
import { Stat, EFFECTIVE_STATS, getShortenedStatKey } from "#app/enums/stat";
export { Nature }; export { Nature };
@ -14,10 +14,9 @@ export function getNatureName(nature: Nature, includeStatEffects: boolean = fals
ret = i18next.t("nature:" + ret as any); ret = i18next.t("nature:" + ret as any);
} }
if (includeStatEffects) { if (includeStatEffects) {
const stats = Utils.getEnumValues(Stat).slice(1);
let increasedStat: Stat | null = null; let increasedStat: Stat | null = null;
let decreasedStat: Stat | null = null; let decreasedStat: Stat | null = null;
for (const stat of stats) { for (const stat of EFFECTIVE_STATS) {
const multiplier = getNatureStatMultiplier(nature, stat); const multiplier = getNatureStatMultiplier(nature, stat);
if (multiplier > 1) { if (multiplier > 1) {
increasedStat = stat; increasedStat = stat;
@ -28,7 +27,7 @@ export function getNatureName(nature: Nature, includeStatEffects: boolean = fals
const textStyle = forStarterSelect ? TextStyle.SUMMARY_ALT : TextStyle.WINDOW; const textStyle = forStarterSelect ? TextStyle.SUMMARY_ALT : TextStyle.WINDOW;
const getTextFrag = !ignoreBBCode ? (text: string, style: TextStyle) => getBBCodeFrag(text, style, uiTheme) : (text: string, style: TextStyle) => text; const getTextFrag = !ignoreBBCode ? (text: string, style: TextStyle) => getBBCodeFrag(text, style, uiTheme) : (text: string, style: TextStyle) => text;
if (increasedStat && decreasedStat) { if (increasedStat && decreasedStat) {
ret = `${getTextFrag(`${ret}${!forStarterSelect ? "\n" : " "}(`, textStyle)}${getTextFrag(`+${getStatName(increasedStat, true)}`, TextStyle.SUMMARY_PINK)}${getTextFrag("/", textStyle)}${getTextFrag(`-${getStatName(decreasedStat, true)}`, TextStyle.SUMMARY_BLUE)}${getTextFrag(")", textStyle)}`; ret = `${getTextFrag(`${ret}${!forStarterSelect ? "\n" : " "}(`, textStyle)}${getTextFrag(`+${i18next.t(getShortenedStatKey(increasedStat))}`, TextStyle.SUMMARY_PINK)}${getTextFrag("/", textStyle)}${getTextFrag(`-${i18next.t(getShortenedStatKey(decreasedStat))}`, TextStyle.SUMMARY_BLUE)}${getTextFrag(")", textStyle)}`;
} else { } else {
ret = getTextFrag(`${ret}${!forStarterSelect ? "\n" : " "}(-)`, textStyle); ret = getTextFrag(`${ret}${!forStarterSelect ? "\n" : " "}(-)`, textStyle);
} }

View File

@ -1,7 +1,7 @@
import { Gender } from "./gender"; import { Gender } from "./gender";
import { PokeballType } from "./pokeball"; import { PokeballType } from "./pokeball";
import Pokemon from "../field/pokemon"; import Pokemon from "../field/pokemon";
import { Stat } from "./pokemon-stat"; import { Stat } from "#enums/stat";
import { Type } from "./type"; import { Type } from "./type";
import * as Utils from "../utils"; import * as Utils from "../utils";
import { SpeciesFormKey } from "./pokemon-species"; import { SpeciesFormKey } from "./pokemon-species";

View File

@ -14,7 +14,7 @@ import { GrowthRate } from "./exp";
import { EvolutionLevel, SpeciesWildEvolutionDelay, pokemonEvolutions, pokemonPrevolutions } from "./pokemon-evolutions"; import { EvolutionLevel, SpeciesWildEvolutionDelay, pokemonEvolutions, pokemonPrevolutions } from "./pokemon-evolutions";
import { Type } from "./type"; import { Type } from "./type";
import { LevelMoves, pokemonFormLevelMoves, pokemonFormLevelMoves as pokemonSpeciesFormLevelMoves, pokemonSpeciesLevelMoves } from "./pokemon-level-moves"; import { LevelMoves, pokemonFormLevelMoves, pokemonFormLevelMoves as pokemonSpeciesFormLevelMoves, pokemonSpeciesLevelMoves } from "./pokemon-level-moves";
import { Stat } from "./pokemon-stat"; import { Stat } from "#enums/stat";
import { Variant, VariantSet, variantColorCache, variantData } from "./variant"; import { Variant, VariantSet, variantColorCache, variantData } from "./variant";
export enum Region { export enum Region {
@ -944,7 +944,7 @@ export function initSpecies() {
new PokemonSpecies(Species.METAPOD, 1, false, false, false, "Cocoon Pokémon", Type.BUG, null, 0.7, 9.9, Abilities.SHED_SKIN, Abilities.NONE, Abilities.SHED_SKIN, 205, 50, 20, 55, 25, 25, 30, 120, 50, 72, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.METAPOD, 1, false, false, false, "Cocoon Pokémon", Type.BUG, null, 0.7, 9.9, Abilities.SHED_SKIN, Abilities.NONE, Abilities.SHED_SKIN, 205, 50, 20, 55, 25, 25, 30, 120, 50, 72, GrowthRate.MEDIUM_FAST, 50, false),
new PokemonSpecies(Species.BUTTERFREE, 1, false, false, false, "Butterfly Pokémon", Type.BUG, Type.FLYING, 1.1, 32, Abilities.COMPOUND_EYES, Abilities.NONE, Abilities.TINTED_LENS, 395, 60, 45, 50, 90, 80, 70, 45, 50, 198, GrowthRate.MEDIUM_FAST, 50, true, true, new PokemonSpecies(Species.BUTTERFREE, 1, false, false, false, "Butterfly Pokémon", Type.BUG, Type.FLYING, 1.1, 32, Abilities.COMPOUND_EYES, Abilities.NONE, Abilities.TINTED_LENS, 395, 60, 45, 50, 90, 80, 70, 45, 50, 198, GrowthRate.MEDIUM_FAST, 50, true, true,
new PokemonForm("Normal", "", Type.BUG, Type.FLYING, 1.1, 32, Abilities.COMPOUND_EYES, Abilities.NONE, Abilities.TINTED_LENS, 395, 60, 45, 50, 90, 80, 70, 45, 50, 198, true, null, true), new PokemonForm("Normal", "", Type.BUG, Type.FLYING, 1.1, 32, Abilities.COMPOUND_EYES, Abilities.NONE, Abilities.TINTED_LENS, 395, 60, 45, 50, 90, 80, 70, 45, 50, 198, true, null, true),
new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.BUG, Type.FLYING, 17, 32, Abilities.TINTED_LENS, Abilities.TINTED_LENS, Abilities.TINTED_LENS, 495, 85, 35, 80, 120, 90, 85, 45, 50, 198, true), new PokemonForm("G-Max", SpeciesFormKey.GIGANTAMAX, Type.BUG, Type.FLYING, 17, 32, Abilities.COMPOUND_EYES, Abilities.COMPOUND_EYES, Abilities.COMPOUND_EYES, 495, 85, 35, 80, 120, 90, 85, 45, 50, 198, true),
), ),
new PokemonSpecies(Species.WEEDLE, 1, false, false, false, "Hairy Bug Pokémon", Type.BUG, Type.POISON, 0.3, 3.2, Abilities.SHIELD_DUST, Abilities.NONE, Abilities.RUN_AWAY, 195, 40, 35, 30, 20, 20, 50, 255, 70, 39, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.WEEDLE, 1, false, false, false, "Hairy Bug Pokémon", Type.BUG, Type.POISON, 0.3, 3.2, Abilities.SHIELD_DUST, Abilities.NONE, Abilities.RUN_AWAY, 195, 40, 35, 30, 20, 20, 50, 255, 70, 39, GrowthRate.MEDIUM_FAST, 50, false),
new PokemonSpecies(Species.KAKUNA, 1, false, false, false, "Cocoon Pokémon", Type.BUG, Type.POISON, 0.6, 10, Abilities.SHED_SKIN, Abilities.NONE, Abilities.SHED_SKIN, 205, 45, 25, 50, 25, 25, 35, 120, 70, 72, GrowthRate.MEDIUM_FAST, 50, false), new PokemonSpecies(Species.KAKUNA, 1, false, false, false, "Cocoon Pokémon", Type.BUG, Type.POISON, 0.6, 10, Abilities.SHED_SKIN, Abilities.NONE, Abilities.SHED_SKIN, 205, 45, 25, 50, 25, 25, 35, 120, 70, 72, GrowthRate.MEDIUM_FAST, 50, false),

View File

@ -1,29 +0,0 @@
import { Stat } from "#enums/stat";
import i18next from "i18next";
export { Stat };
export function getStatName(stat: Stat, shorten: boolean = false) {
let ret: string = "";
switch (stat) {
case Stat.HP:
ret = !shorten ? i18next.t("pokemonInfo:Stat.HP") : i18next.t("pokemonInfo:Stat.HPshortened");
break;
case Stat.ATK:
ret = !shorten ? i18next.t("pokemonInfo:Stat.ATK") : i18next.t("pokemonInfo:Stat.ATKshortened");
break;
case Stat.DEF:
ret = !shorten ? i18next.t("pokemonInfo:Stat.DEF") : i18next.t("pokemonInfo:Stat.DEFshortened");
break;
case Stat.SPATK:
ret = !shorten ? i18next.t("pokemonInfo:Stat.SPATK") : i18next.t("pokemonInfo:Stat.SPATKshortened");
break;
case Stat.SPDEF:
ret = !shorten ? i18next.t("pokemonInfo:Stat.SPDEF") : i18next.t("pokemonInfo:Stat.SPDEFshortened");
break;
case Stat.SPD:
ret = !shorten ? i18next.t("pokemonInfo:Stat.SPD") : i18next.t("pokemonInfo:Stat.SPDshortened");
break;
}
return ret;
}

View File

@ -1,38 +0,0 @@
import { BattleStat, getBattleStatName } from "./battle-stat";
import i18next from "i18next";
export enum TempBattleStat {
ATK,
DEF,
SPATK,
SPDEF,
SPD,
ACC,
CRIT
}
export function getTempBattleStatName(tempBattleStat: TempBattleStat) {
if (tempBattleStat === TempBattleStat.CRIT) {
return i18next.t("modifierType:TempBattleStatBoosterStatName.CRIT");
}
return getBattleStatName(tempBattleStat as integer as BattleStat);
}
export function getTempBattleStatBoosterItemName(tempBattleStat: TempBattleStat) {
switch (tempBattleStat) {
case TempBattleStat.ATK:
return "X Attack";
case TempBattleStat.DEF:
return "X Defense";
case TempBattleStat.SPATK:
return "X Sp. Atk";
case TempBattleStat.SPDEF:
return "X Sp. Def";
case TempBattleStat.SPD:
return "X Speed";
case TempBattleStat.ACC:
return "X Accuracy";
case TempBattleStat.CRIT:
return "Dire Hit";
}
}

View File

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

View File

@ -1,8 +1,75 @@
/** Enum that comprises all possible stat-related attributes, in-battle and permanent, of a Pokemon. */
export enum Stat { export enum Stat {
/** Hit Points */
HP = 0, HP = 0,
/** Attack */
ATK, ATK,
/** Defense */
DEF, DEF,
/** Special Attack */
SPATK, SPATK,
/** Special Defense */
SPDEF, SPDEF,
/** Speed */
SPD, SPD,
/** Accuracy */
ACC,
/** Evasiveness */
EVA
}
/** A constant array comprised of the {@linkcode Stat} values that make up {@linkcode PermanentStat}. */
export const PERMANENT_STATS = [ Stat.HP, Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ] as const;
/** Type used to describe the core, permanent stats of a Pokemon. */
export type PermanentStat = typeof PERMANENT_STATS[number];
/** A constant array comprised of the {@linkcode Stat} values that make up {@linkcode EFfectiveStat}. */
export const EFFECTIVE_STATS = [ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD ] as const;
/** Type used to describe the intersection of core stats and stats that have stages in battle. */
export type EffectiveStat = typeof EFFECTIVE_STATS[number];
/** A constant array comprised of {@linkcode Stat} the values that make up {@linkcode BattleStat}. */
export const BATTLE_STATS = [ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD, Stat.ACC, Stat.EVA ] as const;
/** Type used to describe the stats that have stages which can be incremented and decremented in battle. */
export type BattleStat = typeof BATTLE_STATS[number];
/** A constant array comprised of {@linkcode Stat} the values that make up {@linkcode TempBattleStat}. */
export const TEMP_BATTLE_STATS = [ Stat.ATK, Stat.DEF, Stat.SPATK, Stat.SPDEF, Stat.SPD, Stat.ACC ] as const;
/** Type used to describe the stats that have X item (`TEMP_STAT_STAGE_BOOSTER`) equivalents. */
export type TempBattleStat = typeof TEMP_BATTLE_STATS[number];
/**
* Provides the translation key corresponding to the amount of stat stages and whether those stat stages
* are positive or negative.
* @param stages the amount of stages
* @param isIncrease dictates a negative (`false`) or a positive (`true`) stat stage change
* @returns the translation key fitting the conditions described by {@linkcode stages} and {@linkcode isIncrease}
*/
export function getStatStageChangeDescriptionKey(stages: number, isIncrease: boolean) {
if (stages === 1) {
return isIncrease ? "battle:statRose" : "battle:statFell";
} else if (stages === 2) {
return isIncrease ? "battle:statSharplyRose" : "battle:statHarshlyFell";
} else if (stages <= 6) {
return isIncrease ? "battle:statRoseDrastically" : "battle:statSeverelyFell";
}
return isIncrease ? "battle:statWontGoAnyHigher" : "battle:statWontGoAnyLower";
}
/**
* Provides the translation key corresponding to a given stat which can be translated into its full name.
* @param stat the {@linkcode Stat} to be translated
* @returns the translation key corresponding to the given {@linkcode Stat}
*/
export function getStatKey(stat: Stat) {
return `pokemonInfo:Stat.${Stat[stat]}`;
}
/**
* Provides the translation key corresponding to a given stat which can be translated into its shortened name.
* @param stat the {@linkcode Stat} to be translated
* @returns the translation key corresponding to the given {@linkcode Stat}
*/
export function getShortenedStatKey(stat: PermanentStat) {
return `pokemonInfo:Stat.${Stat[stat]}shortened`;
} }

View File

@ -3,26 +3,24 @@ import BattleScene, { AnySound } from "../battle-scene";
import { Variant, VariantSet, variantColorCache } from "#app/data/variant"; import { Variant, VariantSet, variantColorCache } from "#app/data/variant";
import { variantData } from "#app/data/variant"; import { variantData } from "#app/data/variant";
import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from "../ui/battle-info"; import BattleInfo, { PlayerBattleInfo, EnemyBattleInfo } from "../ui/battle-info";
import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, VariableMoveTypeAttr, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatChangesAttr, SacrificialAttr, VariableMoveCategoryAttr, CounterDamageAttr, StatChangeAttr, RechargeAttr, ChargeAttr, IgnoreWeatherTypeDebuffAttr, BypassBurnDamageReductionAttr, SacrificialAttrOnHit, OneHitKOAccuracyAttr, RespectAttackTypeImmunityAttr } from "../data/move"; import Move, { HighCritAttr, HitsTagAttr, applyMoveAttrs, FixedDamageAttr, VariableAtkAttr, allMoves, MoveCategory, TypelessAttr, CritOnlyAttr, getMoveTargets, OneHitKOAttr, VariableMoveTypeAttr, VariableDefAttr, AttackMove, ModifiedDamageAttr, VariableMoveTypeMultiplierAttr, IgnoreOpponentStatStagesAttr, SacrificialAttr, VariableMoveCategoryAttr, CounterDamageAttr, StatStageChangeAttr, RechargeAttr, ChargeAttr, IgnoreWeatherTypeDebuffAttr, BypassBurnDamageReductionAttr, SacrificialAttrOnHit, OneHitKOAccuracyAttr, RespectAttackTypeImmunityAttr } from "../data/move";
import { default as PokemonSpecies, PokemonSpeciesForm, SpeciesFormKey, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm, getStarterValueFriendshipCap, speciesStarters, starterPassiveAbilities } from "../data/pokemon-species"; import { default as PokemonSpecies, PokemonSpeciesForm, SpeciesFormKey, getFusedSpeciesName, getPokemonSpecies, getPokemonSpeciesForm, getStarterValueFriendshipCap, speciesStarters, starterPassiveAbilities } from "../data/pokemon-species";
import { Constructor } from "#app/utils"; import { Constructor } from "#app/utils";
import * as Utils from "../utils"; import * as Utils from "../utils";
import { Type, TypeDamageMultiplier, getTypeDamageMultiplier, getTypeRgb } from "../data/type"; import { Type, TypeDamageMultiplier, getTypeDamageMultiplier, getTypeRgb } from "../data/type";
import { getLevelTotalExp } from "../data/exp"; import { getLevelTotalExp } from "../data/exp";
import { Stat } from "../data/pokemon-stat"; import { Stat, type PermanentStat, type BattleStat, type EffectiveStat, PERMANENT_STATS, BATTLE_STATS, EFFECTIVE_STATS } from "#enums/stat";
import { DamageMoneyRewardModifier, EnemyDamageBoosterModifier, EnemyDamageReducerModifier, EnemyEndureChanceModifier, EnemyFusionChanceModifier, HiddenAbilityRateBoosterModifier, PokemonBaseStatModifier, PokemonFriendshipBoosterModifier, PokemonHeldItemModifier, PokemonNatureWeightModifier, ShinyRateBoosterModifier, SurviveDamageModifier, TempBattleStatBoosterModifier, StatBoosterModifier, CritBoosterModifier, TerastallizeModifier } from "../modifier/modifier"; import { DamageMoneyRewardModifier, EnemyDamageBoosterModifier, EnemyDamageReducerModifier, EnemyEndureChanceModifier, EnemyFusionChanceModifier, HiddenAbilityRateBoosterModifier, BaseStatModifier, PokemonFriendshipBoosterModifier, PokemonHeldItemModifier, PokemonNatureWeightModifier, ShinyRateBoosterModifier, SurviveDamageModifier, TempStatStageBoosterModifier, TempCritBoosterModifier, StatBoosterModifier, CritBoosterModifier, TerastallizeModifier } from "../modifier/modifier";
import { PokeballType } from "../data/pokeball"; import { PokeballType } from "../data/pokeball";
import { Gender } from "../data/gender"; import { Gender } from "../data/gender";
import { initMoveAnim, loadMoveAnimAssets } from "../data/battle-anims"; import { initMoveAnim, loadMoveAnimAssets } from "../data/battle-anims";
import { Status, StatusEffect, getRandomStatus } from "../data/status-effect"; import { Status, StatusEffect, getRandomStatus } from "../data/status-effect";
import { pokemonEvolutions, pokemonPrevolutions, SpeciesFormEvolution, SpeciesEvolutionCondition, FusionSpeciesFormEvolution } from "../data/pokemon-evolutions"; import { pokemonEvolutions, pokemonPrevolutions, SpeciesFormEvolution, SpeciesEvolutionCondition, FusionSpeciesFormEvolution } from "../data/pokemon-evolutions";
import { reverseCompatibleTms, tmSpecies, tmPoolTiers } from "../data/tms"; import { reverseCompatibleTms, tmSpecies, tmPoolTiers } from "../data/tms";
import { BattleStat } from "../data/battle-stat";
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, ExposedTag, DragonCheerTag, CritBoostTag, TrappedTag } from "../data/battler-tags";
import { WeatherType } from "../data/weather"; import { WeatherType } from "../data/weather";
import { TempBattleStat } from "../data/temp-battle-stat";
import { ArenaTagSide, NoCritTag, WeakenMoveScreenTag } from "../data/arena-tag"; import { ArenaTagSide, NoCritTag, WeakenMoveScreenTag } from "../data/arena-tag";
import { Ability, AbAttr, BattleStatMultiplierAbAttr, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, FieldPriorityMoveImmunityAbAttr, IgnoreOpponentStatChangesAbAttr, MoveImmunityAbAttr, PreDefendFullHpEndureAbAttr, ReceivedMoveDamageMultiplierAbAttr, ReduceStatusEffectDurationAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, WeightMultiplierAbAttr, allAbilities, applyAbAttrs, applyBattleStatMultiplierAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs, UnsuppressableAbilityAbAttr, SuppressFieldAbilitiesAbAttr, NoFusionAbilityAbAttr, MultCritAbAttr, IgnoreTypeImmunityAbAttr, DamageBoostAbAttr, IgnoreTypeStatusEffectImmunityAbAttr, ConditionalCritAbAttr, applyFieldBattleStatMultiplierAbAttrs, FieldMultiplyBattleStatAbAttr, AddSecondStrikeAbAttr, IgnoreOpponentEvasionAbAttr, UserFieldStatusEffectImmunityAbAttr, UserFieldBattlerTagImmunityAbAttr, BattlerTagImmunityAbAttr, MoveTypeChangeAbAttr, FullHpResistTypeAbAttr, applyCheckTrappedAbAttrs, CheckTrappedAbAttr } from "../data/ability"; import { Ability, AbAttr, StatMultiplierAbAttr, BlockCritAbAttr, BonusCritAbAttr, BypassBurnDamageReductionAbAttr, FieldPriorityMoveImmunityAbAttr, IgnoreOpponentStatStagesAbAttr, MoveImmunityAbAttr, PreDefendFullHpEndureAbAttr, ReceivedMoveDamageMultiplierAbAttr, ReduceStatusEffectDurationAbAttr, StabBoostAbAttr, StatusEffectImmunityAbAttr, TypeImmunityAbAttr, WeightMultiplierAbAttr, allAbilities, applyAbAttrs, applyStatMultiplierAbAttrs, applyPreApplyBattlerTagAbAttrs, applyPreAttackAbAttrs, applyPreDefendAbAttrs, applyPreSetStatusAbAttrs, UnsuppressableAbilityAbAttr, SuppressFieldAbilitiesAbAttr, NoFusionAbilityAbAttr, MultCritAbAttr, IgnoreTypeImmunityAbAttr, DamageBoostAbAttr, IgnoreTypeStatusEffectImmunityAbAttr, ConditionalCritAbAttr, applyFieldStatMultiplierAbAttrs, FieldMultiplyStatAbAttr, AddSecondStrikeAbAttr, UserFieldStatusEffectImmunityAbAttr, UserFieldBattlerTagImmunityAbAttr, BattlerTagImmunityAbAttr, MoveTypeChangeAbAttr, FullHpResistTypeAbAttr, applyCheckTrappedAbAttrs, CheckTrappedAbAttr } from "../data/ability";
import PokemonData from "../system/pokemon-data"; import PokemonData from "../system/pokemon-data";
import { BattlerIndex } from "../battle"; import { BattlerIndex } from "../battle";
import { Mode } from "../ui/ui"; import { Mode } from "../ui/ui";
@ -40,7 +38,7 @@ import Overrides from "#app/overrides";
import i18next from "i18next"; import i18next from "i18next";
import { speciesEggMoves } from "../data/egg-moves"; import { speciesEggMoves } from "../data/egg-moves";
import { ModifierTier } from "../modifier/modifier-tier"; import { ModifierTier } from "../modifier/modifier-tier";
import { applyChallenges, ChallengeType } from "#app/data/challenge.js"; import { applyChallenges, ChallengeType } from "#app/data/challenge";
import { Abilities } from "#enums/abilities"; import { Abilities } from "#enums/abilities";
import { ArenaTagType } from "#enums/arena-tag-type"; import { ArenaTagType } from "#enums/arena-tag-type";
import { BattleSpec } from "#enums/battle-spec"; import { BattleSpec } from "#enums/battle-spec";
@ -49,17 +47,17 @@ import { BerryType } from "#enums/berry-type";
import { Biome } from "#enums/biome"; import { Biome } from "#enums/biome";
import { Moves } from "#enums/moves"; import { Moves } from "#enums/moves";
import { Species } from "#enums/species"; import { Species } from "#enums/species";
import { getPokemonNameWithAffix } from "#app/messages";
import { DamagePhase } from "#app/phases/damage-phase";
import { FaintPhase } from "#app/phases/faint-phase";
import { LearnMovePhase } from "#app/phases/learn-move-phase";
import { MoveEffectPhase } from "#app/phases/move-effect-phase";
import { MoveEndPhase } from "#app/phases/move-end-phase";
import { ObtainStatusEffectPhase } from "#app/phases/obtain-status-effect-phase";
import { StatStageChangePhase } from "#app/phases/stat-stage-change-phase";
import { SwitchSummonPhase } from "#app/phases/switch-summon-phase";
import { ToggleDoublePositionPhase } from "#app/phases/toggle-double-position-phase";
import { Challenges } from "#enums/challenges"; import { Challenges } from "#enums/challenges";
import { getPokemonNameWithAffix } from "#app/messages.js";
import { DamagePhase } from "#app/phases/damage-phase.js";
import { FaintPhase } from "#app/phases/faint-phase.js";
import { LearnMovePhase } from "#app/phases/learn-move-phase.js";
import { MoveEffectPhase } from "#app/phases/move-effect-phase.js";
import { MoveEndPhase } from "#app/phases/move-end-phase.js";
import { ObtainStatusEffectPhase } from "#app/phases/obtain-status-effect-phase.js";
import { StatChangePhase } from "#app/phases/stat-change-phase.js";
import { SwitchSummonPhase } from "#app/phases/switch-summon-phase.js";
import { ToggleDoublePositionPhase } from "#app/phases/toggle-double-position-phase.js";
export enum FieldPosition { export enum FieldPosition {
CENTER, CENTER,
@ -119,6 +117,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
public maskEnabled: boolean; public maskEnabled: boolean;
public maskSprite: Phaser.GameObjects.Sprite | null; public maskSprite: Phaser.GameObjects.Sprite | null;
public usedTMs: Moves[];
private shinySparkle: Phaser.GameObjects.Sprite; private shinySparkle: Phaser.GameObjects.Sprite;
constructor(scene: BattleScene, x: number, y: number, species: PokemonSpecies, level: integer, abilityIndex?: integer, formIndex?: integer, gender?: Gender, shiny?: boolean, variant?: Variant, ivs?: integer[], nature?: Nature, dataSource?: Pokemon | PokemonData) { constructor(scene: BattleScene, x: number, y: number, species: PokemonSpecies, level: integer, abilityIndex?: integer, formIndex?: integer, gender?: Gender, shiny?: boolean, variant?: Variant, ivs?: integer[], nature?: Nature, dataSource?: Pokemon | PokemonData) {
@ -195,6 +195,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
this.fusionVariant = dataSource.fusionVariant || 0; this.fusionVariant = dataSource.fusionVariant || 0;
this.fusionGender = dataSource.fusionGender; this.fusionGender = dataSource.fusionGender;
this.fusionLuck = dataSource.fusionLuck; this.fusionLuck = dataSource.fusionLuck;
this.usedTMs = dataSource.usedTMs ?? [];
} else { } else {
this.id = Utils.randSeedInt(4294967296); this.id = Utils.randSeedInt(4294967296);
this.ivs = ivs || Utils.getIvsFromId(this.id); this.ivs = ivs || Utils.getIvsFromId(this.id);
@ -673,49 +674,139 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
}); });
} }
getStat(stat: Stat): integer { /**
* Retrieves the entire set of stats of the {@linkcode Pokemon}.
* @param bypassSummonData prefer actual stats (`true` by default) or in-battle overriden stats (`false`)
* @returns the numeric values of the {@linkcode Pokemon}'s stats
*/
getStats(bypassSummonData: boolean = true): number[] {
if (!bypassSummonData && this.summonData?.stats) {
return this.summonData.stats;
}
return this.stats;
}
/**
* Retrieves the corresponding {@linkcode PermanentStat} of the {@linkcode Pokemon}.
* @param stat the desired {@linkcode PermanentStat}
* @param bypassSummonData prefer actual stats (`true` by default) or in-battle overridden stats (`false`)
* @returns the numeric value of the desired {@linkcode Stat}
*/
getStat(stat: PermanentStat, bypassSummonData: boolean = true): number {
if (!bypassSummonData && this.summonData && (this.summonData.stats[stat] !== 0)) {
return this.summonData.stats[stat];
}
return this.stats[stat]; return this.stats[stat];
} }
getBattleStat(stat: Stat, opponent?: Pokemon, move?: Move, isCritical: boolean = false): integer { /**
if (stat === Stat.HP) { * Writes the value to the corrseponding {@linkcode PermanentStat} of the {@linkcode Pokemon}.
return this.getStat(Stat.HP); *
} * Note that this does nothing if {@linkcode value} is less than 0.
const battleStat = (stat - 1) as BattleStat; * @param stat the desired {@linkcode PermanentStat} to be overwritten
const statLevel = new Utils.IntegerHolder(this.summonData.battleStats[battleStat]); * @param value the desired numeric value
if (opponent) { * @param bypassSummonData write to actual stats (`true` by default) or in-battle overridden stats (`false`)
if (isCritical) { */
switch (stat) { setStat(stat: PermanentStat, value: number, bypassSummonData: boolean = true): void {
case Stat.ATK: if (value >= 0) {
case Stat.SPATK: if (!bypassSummonData && this.summonData) {
statLevel.value = Math.max(statLevel.value, 0); this.summonData.stats[stat] = value;
break; } else {
case Stat.DEF: this.stats[stat] = value;
case Stat.SPDEF:
statLevel.value = Math.min(statLevel.value, 0);
break;
}
}
applyAbAttrs(IgnoreOpponentStatChangesAbAttr, opponent, null, false, statLevel);
if (move) {
applyMoveAttrs(IgnoreOpponentStatChangesAttr, this, opponent, move, statLevel);
} }
} }
if (this.isPlayer()) { }
this.scene.applyModifiers(TempBattleStatBoosterModifier, this.isPlayer(), battleStat as integer as TempBattleStat, statLevel);
/**
* Retrieves the entire set of in-battle stat stages of the {@linkcode Pokemon}.
* @returns the numeric values of the {@linkcode Pokemon}'s in-battle stat stages if available, a fresh stat stage array otherwise
*/
getStatStages(): number[] {
return this.summonData ? this.summonData.statStages : [ 0, 0, 0, 0, 0, 0, 0 ];
}
/**
* Retrieves the in-battle stage of the specified {@linkcode BattleStat}.
* @param stat the {@linkcode BattleStat} whose stage is desired
* @returns the stage of the desired {@linkcode BattleStat} if available, 0 otherwise
*/
getStatStage(stat: BattleStat): number {
return this.summonData ? this.summonData.statStages[stat - 1] : 0;
}
/**
* Writes the value to the in-battle stage of the corresponding {@linkcode BattleStat} of the {@linkcode Pokemon}.
*
* Note that, if the value is not within a range of [-6, 6], it will be forced to the closest range bound.
* @param stat the {@linkcode BattleStat} whose stage is to be overwritten
* @param value the desired numeric value
*/
setStatStage(stat: BattleStat, value: number): void {
if (this.summonData) {
if (value >= -6) {
this.summonData.statStages[stat - 1] = Math.min(value, 6);
} else {
this.summonData.statStages[stat - 1] = Math.max(value, -6);
}
} }
const statValue = new Utils.NumberHolder(this.getStat(stat)); }
/**
* Retrieves the critical-hit stage considering the move used and the Pokemon
* who used it.
* @param source the {@linkcode Pokemon} who using the move
* @param move the {@linkcode Move} being used
* @returns the final critical-hit stage value
*/
getCritStage(source: Pokemon, move: Move): number {
const critStage = new Utils.IntegerHolder(0);
applyMoveAttrs(HighCritAttr, source, this, move, critStage);
this.scene.applyModifiers(CritBoosterModifier, source.isPlayer(), source, critStage);
this.scene.applyModifiers(TempCritBoosterModifier, source.isPlayer(), critStage);
const bonusCrit = new Utils.BooleanHolder(false);
//@ts-ignore
if (applyAbAttrs(BonusCritAbAttr, source, null, false, bonusCrit)) { // TODO: resolve ts-ignore. This is a promise. Checking a promise is bogus.
if (bonusCrit.value) {
critStage.value += 1;
}
}
const critBoostTag = source.getTag(CritBoostTag);
if (critBoostTag) {
if (critBoostTag instanceof DragonCheerTag) {
critStage.value += critBoostTag.typesOnAdd.includes(Type.DRAGON) ? 2 : 1;
} else {
critStage.value += 2;
}
}
console.log(`crit stage: +${critStage.value}`);
return critStage.value;
}
/**
* Calculates and retrieves the final value of a stat considering any held
* items, move effects, opponent abilities, and whether there was a critical
* hit.
* @param stat the desired {@linkcode EffectiveStat}
* @param opponent the target {@linkcode Pokemon}
* @param move the {@linkcode Move} being used
* @param isCritical determines whether a critical hit has occurred or not (`false` by default)
* @returns the final in-battle value of a stat
*/
getEffectiveStat(stat: EffectiveStat, opponent?: Pokemon, move?: Move, isCritical: boolean = false): integer {
const statValue = new Utils.NumberHolder(this.getStat(stat, false));
this.scene.applyModifiers(StatBoosterModifier, this.isPlayer(), this, stat, statValue); this.scene.applyModifiers(StatBoosterModifier, this.isPlayer(), this, stat, statValue);
const fieldApplied = new Utils.BooleanHolder(false); const fieldApplied = new Utils.BooleanHolder(false);
for (const pokemon of this.scene.getField(true)) { for (const pokemon of this.scene.getField(true)) {
applyFieldBattleStatMultiplierAbAttrs(FieldMultiplyBattleStatAbAttr, pokemon, stat, statValue, this, fieldApplied); applyFieldStatMultiplierAbAttrs(FieldMultiplyStatAbAttr, pokemon, stat, statValue, this, fieldApplied);
if (fieldApplied.value) { if (fieldApplied.value) {
break; break;
} }
} }
applyBattleStatMultiplierAbAttrs(BattleStatMultiplierAbAttr, this, battleStat, statValue); applyStatMultiplierAbAttrs(StatMultiplierAbAttr, this, stat, statValue);
let ret = statValue.value * (Math.max(2, 2 + statLevel.value) / Math.max(2, 2 - statLevel.value)); let ret = statValue.value * this.getStatStageMultiplier(stat, opponent, move, isCritical);
switch (stat) { switch (stat) {
case Stat.ATK: case Stat.ATK:
if (this.getTag(BattlerTagType.SLOW_START)) { if (this.getTag(BattlerTagType.SLOW_START)) {
@ -762,24 +853,25 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
if (!this.stats) { if (!this.stats) {
this.stats = [ 0, 0, 0, 0, 0, 0 ]; this.stats = [ 0, 0, 0, 0, 0, 0 ];
} }
const baseStats = this.getSpeciesForm().baseStats.slice(0);
if (this.fusionSpecies) { // Get and manipulate base stats
const fusionBaseStats = this.getFusionSpeciesForm().baseStats; const baseStats = this.getSpeciesForm(true).baseStats.slice();
for (let s = 0; s < this.stats.length; s++) { if (this.isFusion()) {
const fusionBaseStats = this.getFusionSpeciesForm(true).baseStats;
for (const s of PERMANENT_STATS) {
baseStats[s] = Math.ceil((baseStats[s] + fusionBaseStats[s]) / 2); baseStats[s] = Math.ceil((baseStats[s] + fusionBaseStats[s]) / 2);
} }
} else if (this.scene.gameMode.isSplicedOnly) { } else if (this.scene.gameMode.isSplicedOnly) {
for (let s = 0; s < this.stats.length; s++) { for (const s of PERMANENT_STATS) {
baseStats[s] = Math.ceil(baseStats[s] / 2); baseStats[s] = Math.ceil(baseStats[s] / 2);
} }
} }
this.scene.applyModifiers(PokemonBaseStatModifier, this.isPlayer(), this, baseStats); this.scene.applyModifiers(BaseStatModifier, this.isPlayer(), this, baseStats);
const stats = Utils.getEnumValues(Stat);
for (const s of stats) { // Using base stats, calculate and store stats one by one
const isHp = s === Stat.HP; for (const s of PERMANENT_STATS) {
const baseStat = baseStats[s]; let value = Math.floor(((2 * baseStats[s] + this.ivs[s]) * this.level) * 0.01);
let value = Math.floor(((2 * baseStat + this.ivs[s]) * this.level) * 0.01); if (s === Stat.HP) {
if (isHp) {
value = value + this.level + 10; value = value + this.level + 10;
if (this.hasAbility(Abilities.WONDER_GUARD, false, true)) { if (this.hasAbility(Abilities.WONDER_GUARD, false, true)) {
value = 1; value = 1;
@ -800,7 +892,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
value = Math.max(Math[natureStatMultiplier.value > 1 ? "ceil" : "floor"](value * natureStatMultiplier.value), 1); value = Math.max(Math[natureStatMultiplier.value > 1 ? "ceil" : "floor"](value * natureStatMultiplier.value), 1);
} }
} }
this.stats[s] = value;
this.setStat(s, value);
} }
} }
@ -935,7 +1028,11 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
if (this.metBiome === -1 && !this.scene.gameMode.isFreshStartChallenge() && !this.scene.gameMode.isDaily) { if (this.metBiome === -1 && !this.scene.gameMode.isFreshStartChallenge() && !this.scene.gameMode.isDaily) {
levelMoves = this.getUnlockedEggMoves().concat(levelMoves); levelMoves = this.getUnlockedEggMoves().concat(levelMoves);
} }
return levelMoves.filter(lm => !this.moveset.some(m => m?.moveId === lm)); if (Array.isArray(this.usedTMs) && this.usedTMs.length > 0) {
levelMoves = this.usedTMs.filter(m => !levelMoves.includes(m)).concat(levelMoves);
}
levelMoves = levelMoves.filter(lm => !this.moveset.some(m => m?.moveId === lm));
return levelMoves;
} }
/** /**
@ -1371,7 +1468,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
const types = this.getTypes(true); const types = this.getTypes(true);
const enemyTypes = opponent.getTypes(true, true); const enemyTypes = opponent.getTypes(true, true);
/** Is this Pokemon faster than the opponent? */ /** Is this Pokemon faster than the opponent? */
const outspeed = (this.isActive(true) ? this.getBattleStat(Stat.SPD, opponent) : this.getStat(Stat.SPD)) >= opponent.getBattleStat(Stat.SPD, this); const outspeed = (this.isActive(true) ? this.getEffectiveStat(Stat.SPD, opponent) : this.getStat(Stat.SPD, false)) >= opponent.getEffectiveStat(Stat.SPD, this);
/** /**
* Based on how effective this Pokemon's types are offensively against the opponent's types. * Based on how effective this Pokemon's types are offensively against the opponent's types.
* This score is increased by 25 percent if this Pokemon is faster than the opponent. * This score is increased by 25 percent if this Pokemon is faster than the opponent.
@ -1750,7 +1847,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
movePool = movePool.map(m => [m[0], m[1] * (!!allMoves[m[0]].hasAttr(SacrificialAttr) ? 0.5 : 1)]); movePool = movePool.map(m => [m[0], m[1] * (!!allMoves[m[0]].hasAttr(SacrificialAttr) ? 0.5 : 1)]);
movePool = movePool.map(m => [m[0], m[1] * (!!allMoves[m[0]].hasAttr(SacrificialAttrOnHit) ? 0.5 : 1)]); movePool = movePool.map(m => [m[0], m[1] * (!!allMoves[m[0]].hasAttr(SacrificialAttrOnHit) ? 0.5 : 1)]);
// Trainers get a weight bump to stat buffing moves // Trainers get a weight bump to stat buffing moves
movePool = movePool.map(m => [m[0], m[1] * (allMoves[m[0]].getAttrs(StatChangeAttr).some(a => a.levels > 1 && a.selfTarget) ? 1.25 : 1)]); movePool = movePool.map(m => [m[0], m[1] * (allMoves[m[0]].getAttrs(StatStageChangeAttr).some(a => a.stages > 1 && a.selfTarget) ? 1.25 : 1)]);
// Trainers get a weight decrease to multiturn moves // Trainers get a weight decrease to multiturn moves
movePool = movePool.map(m => [m[0], m[1] * (!!allMoves[m[0]].hasAttr(ChargeAttr) || !!allMoves[m[0]].hasAttr(RechargeAttr) ? 0.7 : 1)]); movePool = movePool.map(m => [m[0], m[1] * (!!allMoves[m[0]].hasAttr(ChargeAttr) || !!allMoves[m[0]].hasAttr(RechargeAttr) ? 0.7 : 1)]);
} }
@ -1762,8 +1859,10 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
movePool = movePool.map(m => [m[0], m[1] * (allMoves[m[0]].category === MoveCategory.STATUS ? 1 : Math.max(Math.min(allMoves[m[0]].power/maxPower, 1), 0.5))]); movePool = movePool.map(m => [m[0], m[1] * (allMoves[m[0]].category === MoveCategory.STATUS ? 1 : Math.max(Math.min(allMoves[m[0]].power/maxPower, 1), 0.5))]);
// Weight damaging moves against the lower stat // Weight damaging moves against the lower stat
const worseCategory: MoveCategory = this.stats[Stat.ATK] > this.stats[Stat.SPATK] ? MoveCategory.SPECIAL : MoveCategory.PHYSICAL; const atk = this.getStat(Stat.ATK);
const statRatio = worseCategory === MoveCategory.PHYSICAL ? this.stats[Stat.ATK]/this.stats[Stat.SPATK] : this.stats[Stat.SPATK]/this.stats[Stat.ATK]; const spAtk = this.getStat(Stat.SPATK);
const worseCategory: MoveCategory = atk > spAtk ? MoveCategory.SPECIAL : MoveCategory.PHYSICAL;
const statRatio = worseCategory === MoveCategory.PHYSICAL ? atk / spAtk : spAtk / atk;
movePool = movePool.map(m => [m[0], m[1] * (allMoves[m[0]].category === worseCategory ? statRatio : 1)]); movePool = movePool.map(m => [m[0], m[1] * (allMoves[m[0]].category === worseCategory ? statRatio : 1)]);
let weightMultiplier = 0.9; // The higher this is the more the game weights towards higher level moves. At 0 all moves are equal weight. let weightMultiplier = 0.9; // The higher this is the more the game weights towards higher level moves. At 0 all moves are equal weight.
@ -1949,6 +2048,48 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
return this instanceof PlayerPokemon ? this.scene.getPlayerField() : this.scene.getEnemyField(); return this instanceof PlayerPokemon ? this.scene.getPlayerField() : this.scene.getEnemyField();
} }
/**
* Calculates the stat stage multiplier of the user against an opponent.
*
* Note that this does not apply to evasion or accuracy
* @see {@linkcode getAccuracyMultiplier}
* @param stat the desired {@linkcode EffectiveStat}
* @param opponent the target {@linkcode Pokemon}
* @param move the {@linkcode Move} being used
* @param isCritical determines whether a critical hit has occurred or not (`false` by default)
* @return the stat stage multiplier to be used for effective stat calculation
*/
getStatStageMultiplier(stat: EffectiveStat, opponent?: Pokemon, move?: Move, isCritical: boolean = false): number {
const statStage = new Utils.IntegerHolder(this.getStatStage(stat));
const ignoreStatStage = new Utils.BooleanHolder(false);
if (opponent) {
if (isCritical) {
switch (stat) {
case Stat.ATK:
case Stat.SPATK:
statStage.value = Math.max(statStage.value, 0);
break;
case Stat.DEF:
case Stat.SPDEF:
statStage.value = Math.min(statStage.value, 0);
break;
}
}
applyAbAttrs(IgnoreOpponentStatStagesAbAttr, opponent, null, false, stat, ignoreStatStage);
if (move) {
applyMoveAttrs(IgnoreOpponentStatStagesAttr, this, opponent, move, ignoreStatStage);
}
}
if (!ignoreStatStage.value) {
const statStageMultiplier = new Utils.NumberHolder(Math.max(2, 2 + statStage.value) / Math.max(2, 2 - statStage.value));
this.scene.applyModifiers(TempStatStageBoosterModifier, this.isPlayer(), stat, statStageMultiplier);
return Math.min(statStageMultiplier.value, 4);
}
return 1;
}
/** /**
* Calculates the accuracy multiplier of the user against a target. * Calculates the accuracy multiplier of the user against a target.
* *
@ -1965,34 +2106,38 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
return 1; return 1;
} }
const userAccuracyLevel = new Utils.IntegerHolder(this.summonData.battleStats[BattleStat.ACC]); const userAccStage = new Utils.IntegerHolder(this.getStatStage(Stat.ACC));
const targetEvasionLevel = new Utils.IntegerHolder(target.summonData.battleStats[BattleStat.EVA]); const targetEvaStage = new Utils.IntegerHolder(target.getStatStage(Stat.EVA));
applyAbAttrs(IgnoreOpponentStatChangesAbAttr, target, null, false, userAccuracyLevel); const ignoreAccStatStage = new Utils.BooleanHolder(false);
applyAbAttrs(IgnoreOpponentStatChangesAbAttr, this, null, false, targetEvasionLevel); const ignoreEvaStatStage = new Utils.BooleanHolder(false);
applyAbAttrs(IgnoreOpponentEvasionAbAttr, this, null, false, targetEvasionLevel);
applyMoveAttrs(IgnoreOpponentStatChangesAttr, this, target, sourceMove, targetEvasionLevel); applyAbAttrs(IgnoreOpponentStatStagesAbAttr, target, null, false, Stat.ACC, ignoreAccStatStage);
this.scene.applyModifiers(TempBattleStatBoosterModifier, this.isPlayer(), TempBattleStat.ACC, userAccuracyLevel); applyAbAttrs(IgnoreOpponentStatStagesAbAttr, this, null, false, Stat.EVA, ignoreEvaStatStage);
applyMoveAttrs(IgnoreOpponentStatStagesAttr, this, target, sourceMove, ignoreEvaStatStage);
this.scene.applyModifiers(TempStatStageBoosterModifier, this.isPlayer(), Stat.ACC, userAccStage);
userAccStage.value = ignoreAccStatStage.value ? 0 : Math.min(userAccStage.value, 6);
targetEvaStage.value = ignoreEvaStatStage.value ? 0 : targetEvaStage.value;
if (target.findTag(t => t instanceof ExposedTag)) { if (target.findTag(t => t instanceof ExposedTag)) {
targetEvasionLevel.value = Math.min(0, targetEvasionLevel.value); targetEvaStage.value = Math.min(0, targetEvaStage.value);
} }
const accuracyMultiplier = new Utils.NumberHolder(1); const accuracyMultiplier = new Utils.NumberHolder(1);
if (userAccuracyLevel.value !== targetEvasionLevel.value) { if (userAccStage.value !== targetEvaStage.value) {
accuracyMultiplier.value = userAccuracyLevel.value > targetEvasionLevel.value accuracyMultiplier.value = userAccStage.value > targetEvaStage.value
? (3 + Math.min(userAccuracyLevel.value - targetEvasionLevel.value, 6)) / 3 ? (3 + Math.min(userAccStage.value - targetEvaStage.value, 6)) / 3
: 3 / (3 + Math.min(targetEvasionLevel.value - userAccuracyLevel.value, 6)); : 3 / (3 + Math.min(targetEvaStage.value - userAccStage.value, 6));
} }
applyBattleStatMultiplierAbAttrs(BattleStatMultiplierAbAttr, this, BattleStat.ACC, accuracyMultiplier, false, sourceMove); applyStatMultiplierAbAttrs(StatMultiplierAbAttr, this, Stat.ACC, accuracyMultiplier, false, sourceMove);
const evasionMultiplier = new Utils.NumberHolder(1); const evasionMultiplier = new Utils.NumberHolder(1);
applyBattleStatMultiplierAbAttrs(BattleStatMultiplierAbAttr, target, BattleStat.EVA, evasionMultiplier); applyStatMultiplierAbAttrs(StatMultiplierAbAttr, target, Stat.EVA, evasionMultiplier);
accuracyMultiplier.value /= evasionMultiplier.value; return accuracyMultiplier.value / evasionMultiplier.value;
return accuracyMultiplier.value;
} }
/** /**
@ -2079,29 +2224,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
if (critOnly.value || critAlways) { if (critOnly.value || critAlways) {
isCritical = true; isCritical = true;
} else { } else {
const critLevel = new Utils.IntegerHolder(0); const critChance = [24, 8, 2, 1][Math.max(0, Math.min(this.getCritStage(source, move), 3))];
applyMoveAttrs(HighCritAttr, source, this, move, critLevel);
this.scene.applyModifiers(CritBoosterModifier, source.isPlayer(), source, critLevel);
this.scene.applyModifiers(TempBattleStatBoosterModifier, source.isPlayer(), TempBattleStat.CRIT, critLevel);
const bonusCrit = new Utils.BooleanHolder(false);
//@ts-ignore
if (applyAbAttrs(BonusCritAbAttr, source, null, false, bonusCrit)) { // TODO: resolve ts-ignore. This is a promise. Checking a promise is bogus.
if (bonusCrit.value) {
critLevel.value += 1;
}
}
const critBoostTag = source.getTag(CritBoostTag);
if (critBoostTag) {
if (critBoostTag instanceof DragonCheerTag) {
critLevel.value += critBoostTag.typesOnAdd.includes(Type.DRAGON) ? 2 : 1;
} else {
critLevel.value += 2;
}
}
console.log(`crit stage: +${critLevel.value}`);
const critChance = [24, 8, 2, 1][Math.max(0, Math.min(critLevel.value, 3))];
isCritical = critChance === 1 || !this.scene.randBattleSeedInt(critChance); isCritical = critChance === 1 || !this.scene.randBattleSeedInt(critChance);
if (Overrides.NEVER_CRIT_OVERRIDE) { if (Overrides.NEVER_CRIT_OVERRIDE) {
isCritical = false; isCritical = false;
@ -2115,8 +2238,8 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
isCritical = false; isCritical = false;
} }
} }
const sourceAtk = new Utils.IntegerHolder(source.getBattleStat(isPhysical ? Stat.ATK : Stat.SPATK, this, undefined, isCritical)); const sourceAtk = new Utils.IntegerHolder(source.getEffectiveStat(isPhysical ? Stat.ATK : Stat.SPATK, this, undefined, isCritical));
const targetDef = new Utils.IntegerHolder(this.getBattleStat(isPhysical ? Stat.DEF : Stat.SPDEF, source, move, isCritical)); const targetDef = new Utils.IntegerHolder(this.getEffectiveStat(isPhysical ? Stat.DEF : Stat.SPDEF, source, move, isCritical));
const criticalMultiplier = new Utils.NumberHolder(isCritical ? 1.5 : 1); const criticalMultiplier = new Utils.NumberHolder(isCritical ? 1.5 : 1);
applyAbAttrs(MultCritAbAttr, source, null, false, criticalMultiplier); applyAbAttrs(MultCritAbAttr, source, null, false, criticalMultiplier);
const screenMultiplier = new Utils.NumberHolder(1); const screenMultiplier = new Utils.NumberHolder(1);
@ -2527,24 +2650,23 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
* @param source {@linkcode Pokemon} the pokemon whose stats/Tags are to be passed on from, ie: the Pokemon using Baton Pass * @param source {@linkcode Pokemon} the pokemon whose stats/Tags are to be passed on from, ie: the Pokemon using Baton Pass
*/ */
transferSummon(source: Pokemon): void { transferSummon(source: Pokemon): void {
const battleStats = Utils.getEnumValues(BattleStat); // Copy all stat stages
for (const stat of battleStats) { for (const s of BATTLE_STATS) {
this.summonData.battleStats[stat] = source.summonData.battleStats[stat]; const sourceStage = source.getStatStage(s);
if ((this instanceof PlayerPokemon) && (sourceStage === 6)) {
this.scene.validateAchv(achvs.TRANSFER_MAX_STAT_STAGE);
}
this.setStatStage(s, sourceStage);
} }
for (const tag of source.summonData.tags) { for (const tag of source.summonData.tags) {
if (!tag.isBatonPassable) {
// bypass those can not be passed via Baton Pass
const excludeTagTypes = new Set([BattlerTagType.DROWSY, BattlerTagType.INFATUATED, BattlerTagType.FIRE_BOOST]);
if (excludeTagTypes.has(tag.tagType)) {
continue; continue;
} }
this.summonData.tags.push(tag); this.summonData.tags.push(tag);
} }
if (this instanceof PlayerPokemon && source.summonData.battleStats.find(bs => bs === 6)) {
this.scene.validateAchv(achvs.TRANSFER_MAX_BATTLE_STAT);
}
this.updateInfo(); this.updateInfo();
} }
@ -3357,6 +3479,7 @@ export default interface Pokemon {
export class PlayerPokemon extends Pokemon { export class PlayerPokemon extends Pokemon {
public compatibleTms: Moves[]; public compatibleTms: Moves[];
public usedTms: Moves[];
constructor(scene: BattleScene, species: PokemonSpecies, level: integer, abilityIndex?: integer, formIndex?: integer, gender?: Gender, shiny?: boolean, variant?: Variant, ivs?: integer[], nature?: Nature, dataSource?: Pokemon | PokemonData) { constructor(scene: BattleScene, species: PokemonSpecies, level: integer, abilityIndex?: integer, formIndex?: integer, gender?: Gender, shiny?: boolean, variant?: Variant, ivs?: integer[], nature?: Nature, dataSource?: Pokemon | PokemonData) {
super(scene, 106, 148, species, level, abilityIndex, formIndex, gender, shiny, variant, ivs, nature, dataSource); super(scene, 106, 148, species, level, abilityIndex, formIndex, gender, shiny, variant, ivs, nature, dataSource);
@ -3380,6 +3503,7 @@ export class PlayerPokemon extends Pokemon {
} }
} }
this.generateCompatibleTms(); this.generateCompatibleTms();
this.usedTms = [];
} }
initBattleInfo(): void { initBattleInfo(): void {
@ -3638,6 +3762,9 @@ export class PlayerPokemon extends Pokemon {
newPokemon.moveset = this.moveset.slice(); newPokemon.moveset = this.moveset.slice();
newPokemon.moveset = this.copyMoveset(); newPokemon.moveset = this.copyMoveset();
newPokemon.luck = this.luck; newPokemon.luck = this.luck;
newPokemon.metLevel = this.metLevel;
newPokemon.metBiome = this.metBiome;
newPokemon.metSpecies = this.metSpecies;
newPokemon.fusionSpecies = this.fusionSpecies; newPokemon.fusionSpecies = this.fusionSpecies;
newPokemon.fusionFormIndex = this.fusionFormIndex; newPokemon.fusionFormIndex = this.fusionFormIndex;
newPokemon.fusionAbilityIndex = this.fusionAbilityIndex; newPokemon.fusionAbilityIndex = this.fusionAbilityIndex;
@ -3717,16 +3844,17 @@ export class PlayerPokemon extends Pokemon {
this.scene.gameData.gameStats.pokemonFused++; this.scene.gameData.gameStats.pokemonFused++;
// Store the average HP% that each Pokemon has // Store the average HP% that each Pokemon has
const newHpPercent = ((pokemon.hp / pokemon.stats[Stat.HP]) + (this.hp / this.stats[Stat.HP])) / 2; const maxHp = this.getMaxHp();
const newHpPercent = ((pokemon.hp / pokemon.getMaxHp()) + (this.hp / maxHp)) / 2;
this.generateName(); this.generateName();
this.calculateStats(); this.calculateStats();
// Set this Pokemon's HP to the average % of both fusion components // Set this Pokemon's HP to the average % of both fusion components
this.hp = Math.round(this.stats[Stat.HP] * newHpPercent); this.hp = Math.round(maxHp * newHpPercent);
if (!this.isFainted()) { if (!this.isFainted()) {
// If this Pokemon hasn't fainted, make sure the HP wasn't set over the new maximum // If this Pokemon hasn't fainted, make sure the HP wasn't set over the new maximum
this.hp = Math.min(this.hp, this.stats[Stat.HP]); this.hp = Math.min(this.hp, maxHp);
this.status = getRandomStatus(this.status, pokemon.status); // Get a random valid status between the two this.status = getRandomStatus(this.status, pokemon.status); // Get a random valid status between the two
} else if (!pokemon.isFainted()) { } else if (!pokemon.isFainted()) {
// If this Pokemon fainted but the other hasn't, make sure the HP wasn't set to zero // If this Pokemon fainted but the other hasn't, make sure the HP wasn't set to zero
@ -4176,7 +4304,7 @@ export class EnemyPokemon extends Pokemon {
//console.log('damage', damage, 'segment', segmentsBypassed + 1, 'segment size', segmentSize, 'damage needed', Math.round(segmentSize * Math.pow(2, segmentsBypassed + 1))); //console.log('damage', damage, 'segment', segmentsBypassed + 1, 'segment size', segmentSize, 'damage needed', Math.round(segmentSize * Math.pow(2, segmentsBypassed + 1)));
} }
damage = hpRemainder + Math.round(segmentSize * segmentsBypassed); damage = Utils.toDmgValue(this.hp - hpThreshold + segmentSize * segmentsBypassed);
clearedBossSegmentIndex = s - segmentsBypassed; clearedBossSegmentIndex = s - segmentsBypassed;
} }
break; break;
@ -4219,43 +4347,40 @@ export class EnemyPokemon extends Pokemon {
handleBossSegmentCleared(segmentIndex: integer): void { handleBossSegmentCleared(segmentIndex: integer): void {
while (segmentIndex - 1 < this.bossSegmentIndex) { while (segmentIndex - 1 < this.bossSegmentIndex) {
let boostedStat = BattleStat.RAND; // Filter out already maxed out stat stages and weigh the rest based on existing stats
const leftoverStats = EFFECTIVE_STATS.filter((s: EffectiveStat) => this.getStatStage(s) < 6);
const statWeights = leftoverStats.map((s: EffectiveStat) => this.getStat(s, false));
const battleStats = Utils.getEnumValues(BattleStat).slice(0, -3); let boostedStat: EffectiveStat;
const statWeights = new Array().fill(battleStats.length).filter((bs: BattleStat) => this.summonData.battleStats[bs] < 6).map((bs: BattleStat) => this.getStat(bs + 1)); const statThresholds: number[] = [];
const statThresholds: integer[] = [];
let totalWeight = 0; let totalWeight = 0;
for (const bs of battleStats) {
totalWeight += statWeights[bs]; for (const i in statWeights) {
totalWeight += statWeights[i];
statThresholds.push(totalWeight); statThresholds.push(totalWeight);
} }
// Pick a random stat from the leftover stats to increase its stages
const randInt = Utils.randSeedInt(totalWeight); const randInt = Utils.randSeedInt(totalWeight);
for (const i in statThresholds) {
for (const bs of battleStats) { if (randInt < statThresholds[i]) {
if (randInt < statThresholds[bs]) { boostedStat = leftoverStats[i];
boostedStat = bs;
break; break;
} }
} }
let statLevels = 1; let stages = 1;
switch (segmentIndex) { // increase the boost if the boss has at least 3 segments and we passed last shield
case 1: if (this.bossSegments >= 3 && this.bossSegmentIndex === 1) {
if (this.bossSegments >= 3) { stages++;
statLevels++; }
} // increase the boost if the boss has at least 5 segments and we passed the second to last shield
break; if (this.bossSegments >= 5 && this.bossSegmentIndex === 2) {
case 2: stages++;
if (this.bossSegments >= 5) {
statLevels++;
}
break;
} }
this.scene.unshiftPhase(new StatChangePhase(this.scene, this.getBattlerIndex(), true, [ boostedStat ], statLevels, true, true)); this.scene.unshiftPhase(new StatStageChangePhase(this.scene, this.getBattlerIndex(), true, [ boostedStat! ], stages, true, true));
this.bossSegmentIndex--; this.bossSegmentIndex--;
} }
} }
@ -4331,7 +4456,7 @@ export interface AttackMoveResult {
} }
export class PokemonSummonData { export class PokemonSummonData {
public battleStats: number[] = [ 0, 0, 0, 0, 0, 0, 0 ]; public statStages: number[] = [ 0, 0, 0, 0, 0, 0, 0 ];
public moveQueue: QueuedMove[] = []; public moveQueue: QueuedMove[] = [];
public disabledMove: Moves = Moves.NONE; public disabledMove: Moves = Moves.NONE;
public disabledTurns: number = 0; public disabledTurns: number = 0;
@ -4344,7 +4469,7 @@ export class PokemonSummonData {
public ability: Abilities = Abilities.NONE; public ability: Abilities = Abilities.NONE;
public gender: Gender; public gender: Gender;
public fusionGender: Gender; public fusionGender: Gender;
public stats: number[]; public stats: number[] = [ 0, 0, 0, 0, 0, 0 ];
public moveset: (PokemonMove | null)[]; public moveset: (PokemonMove | null)[];
// If not initialized this value will not be populated from save data. // If not initialized this value will not be populated from save data.
public types: Type[] = []; public types: Type[] = [];
@ -4375,8 +4500,8 @@ export class PokemonTurnData {
public damageTaken: number = 0; public damageTaken: number = 0;
public attacksReceived: AttackMoveResult[] = []; public attacksReceived: AttackMoveResult[] = [];
public order: number; public order: number;
public battleStatsIncreased: boolean = false; public statStagesIncreased: boolean = false;
public battleStatsDecreased: boolean = false; public statStagesDecreased: boolean = false;
} }
export enum AiType { export enum AiType {

View File

@ -37,8 +37,7 @@ export interface ModifierTypeTranslationEntries {
ModifierType: { [key: string]: ModifierTypeTranslationEntry }, ModifierType: { [key: string]: ModifierTypeTranslationEntry },
SpeciesBoosterItem: { [key: string]: ModifierTypeTranslationEntry }, SpeciesBoosterItem: { [key: string]: ModifierTypeTranslationEntry },
AttackTypeBoosterItem: SimpleTranslationEntries, AttackTypeBoosterItem: SimpleTranslationEntries,
TempBattleStatBoosterItem: SimpleTranslationEntries, TempStatStageBoosterItem: SimpleTranslationEntries,
TempBattleStatBoosterStatName: SimpleTranslationEntries,
BaseStatBoosterItem: SimpleTranslationEntries, BaseStatBoosterItem: SimpleTranslationEntries,
EvolutionItem: SimpleTranslationEntries, EvolutionItem: SimpleTranslationEntries,
FormChangeItem: SimpleTranslationEntries, FormChangeItem: SimpleTranslationEntries,

View File

@ -78,6 +78,7 @@ export class LoadingScene extends SceneBase {
this.loadAtlas("overlay_hp_boss", "ui"); this.loadAtlas("overlay_hp_boss", "ui");
this.loadImage("overlay_exp", "ui"); this.loadImage("overlay_exp", "ui");
this.loadImage("icon_owned", "ui"); this.loadImage("icon_owned", "ui");
this.loadImage("icon_egg_move", "ui");
this.loadImage("ability_bar_left", "ui"); this.loadImage("ability_bar_left", "ui");
this.loadImage("bgm_bar", "ui"); this.loadImage("bgm_bar", "ui");
this.loadImage("party_exp_bar", "ui"); this.loadImage("party_exp_bar", "ui");
@ -98,6 +99,8 @@ export class LoadingScene extends SceneBase {
this.loadImage("ha_capsule", "ui", "ha_capsule.png"); this.loadImage("ha_capsule", "ui", "ha_capsule.png");
this.loadImage("champion_ribbon", "ui", "champion_ribbon.png"); this.loadImage("champion_ribbon", "ui", "champion_ribbon.png");
this.loadImage("icon_spliced", "ui"); this.loadImage("icon_spliced", "ui");
this.loadImage("icon_lock", "ui", "icon_lock.png");
this.loadImage("icon_stop", "ui", "icon_stop.png");
this.loadImage("icon_tera", "ui"); this.loadImage("icon_tera", "ui");
this.loadImage("type_tera", "ui"); this.loadImage("type_tera", "ui");
this.loadAtlas("type_bgs", "ui"); this.loadAtlas("type_bgs", "ui");
@ -244,7 +247,7 @@ export class LoadingScene extends SceneBase {
} else { } else {
this.loadAtlas("types", ""); this.loadAtlas("types", "");
} }
const availableLangs = ["en", "de", "it", "fr", "ja", "ko", "es", "pt_BR", "zh_CN"]; const availableLangs = ["en", "de", "it", "fr", "ja", "ko", "es", "pt-BR", "zh-CN"];
if (lang && availableLangs.includes(lang)) { if (lang && availableLangs.includes(lang)) {
this.loadImage("september-update-"+lang, "events"); this.loadImage("september-update-"+lang, "events");
} else { } else {
@ -270,6 +273,7 @@ export class LoadingScene extends SceneBase {
this.loadImage("gacha_knob", "egg"); this.loadImage("gacha_knob", "egg");
this.loadImage("egg_list_bg", "ui"); this.loadImage("egg_list_bg", "ui");
this.loadImage("egg_summary_bg", "ui");
this.loadImage("end_m", "cg"); this.loadImage("end_m", "cg");
this.loadImage("end_f", "cg"); this.loadImage("end_f", "cg");

View File

@ -89,7 +89,7 @@
"name": "Bänder-Meister", "name": "Bänder-Meister",
"name_female": "Bänder-Meisterin" "name_female": "Bänder-Meisterin"
}, },
"TRANSFER_MAX_BATTLE_STAT": { "TRANSFER_MAX_STAT_STAGE": {
"name": "Teamwork", "name": "Teamwork",
"description": "Nutze Staffette, während der Anwender mindestens eines Statuswertes maximiert hat." "description": "Nutze Staffette, während der Anwender mindestens eines Statuswertes maximiert hat."
}, },
@ -274,4 +274,4 @@
"name": "Spieglein, Spieglein an der Wand", "name": "Spieglein, Spieglein an der Wand",
"description": "Schließe die 'Umkehrkampf' Herausforderung ab" "description": "Schließe die 'Umkehrkampf' Herausforderung ab"
} }
} }

View File

@ -94,5 +94,6 @@
"retryBattle": "Möchtest du vom Beginn des Kampfes neustarten?", "retryBattle": "Möchtest du vom Beginn des Kampfes neustarten?",
"unlockedSomething": "{{unlockedThing}} wurde freigeschaltet.", "unlockedSomething": "{{unlockedThing}} wurde freigeschaltet.",
"congratulations": "Glückwunsch!", "congratulations": "Glückwunsch!",
"beatModeFirstTime": "{{speciesName}} hat den {{gameMode}} Modus zum ersten Mal beendet! Du erhältst {{newModifier}}!" "beatModeFirstTime": "{{speciesName}} hat den {{gameMode}} Modus zum ersten Mal beendet! Du erhältst {{newModifier}}!",
"eggSkipPrompt": "Zur Ei-Zusammenfassung springen?"
} }

View File

@ -1,10 +1,11 @@
{ {
"noneSelected": "Keine ausgewählt",
"title": "Herausforderungsmodifikatoren", "title": "Herausforderungsmodifikatoren",
"illegalEvolution": "{{pokemon}} hat sich in ein Pokémon verwandelt, dass für diese Herausforderung nicht zulässig ist!", "illegalEvolution": "{{pokemon}} hat sich in ein Pokémon verwandelt, dass für diese Herausforderung nicht zulässig ist!",
"singleGeneration": { "singleGeneration": {
"name": "Mono-Generation", "name": "Mono-Generation",
"desc": "Du kannst nur Pokémon aus der {{gen}} Generation verwenden.", "desc": "Du kannst nur Pokémon aus der {{gen}} Generation verwenden.",
"desc_default": "Du kannst nur Pokémon gewählten Generation verwenden.", "desc_default": "Du kannst nur Pokémon aus der gewählten Generation verwenden.",
"gen_1": "ersten", "gen_1": "ersten",
"gen_2": "zweiten", "gen_2": "zweiten",
"gen_3": "dritten", "gen_3": "dritten",

View File

@ -1,6 +1,6 @@
{ {
"ending": "@c{smile}Oh? Du hast gewonnen?@d{96} @c{smile_eclosed}Ich schätze, das hätte ich wissen sollen.\n$Aber, du bist jetzt zurück.\n$@c{smile}Es ist vorbei.@d{64} Du hast die Schleife beendet.\n$@c{serious_smile_fists}Du hast auch deinen Traum erfüllt, nicht wahr?\nDu hast nicht einmal verloren.\n$@c{neutral}Ich bin der Einzige, der sich daran erinnern wird, was du getan hast.@d{96}\n$Ich schätze, das ist in Ordnung, oder?\n$@c{serious_smile_fists}Deine Legende wird immer in unseren Herzen weiterleben.\n$@c{smile_eclosed}Wie auch immer, ich habe genug von diesem Ort, oder nicht? Lass uns nach Hause gehen.\n$@c{serious_smile_fists}Vielleicht können wir, wenn wir zurück sind, noch einen Kampf haben?\n$Wenn du dazu bereit bist.", "ending": "@c{shock}Du bist zurück?@d{32} Bedeutet das…@d{96} du hast gewonnen?!\n$@c{smile_ehalf}Ich hätte wissen sollen, dass du es in dir hast.\n$@c{smile_eclosed}Natürlich… ich hatte immer dieses Gefühl.\n$@c{smile}Es ist jetzt vorbei, richtig? Du hast die Schleife beendet.\n$@c{smile_ehalf}Du hast auch deinen Traum erfüllt, nicht wahr?\n$Du hast nicht einmal verloren.\n$Ich werde die Einzige sein, die sich daran erinnert, was du getan hast.\n$@c{angry_mopen}Ich werde versuchen, es nicht zu vergessen!\n$@c{smile_wave_wink}Nur ein Scherz!@d{64} @c{smile}Ich würde es nie vergessen.@d{32}\n$Deine Legende wird in unseren Herzen weiterleben.\n$@c{smile_wave}Wie auch immer,@d{64} es wird spät…@d{96} denke ich?\nEs ist schwer zu sagen an diesem Ort.\n$Lass uns nach Hause gehen. \n$@c{smile_wave_wink}Vielleicht können wir morgen noch einen Kampf haben, der alten Zeiten willen?",
"ending_female": "@c{shock}Du bist zurück?@d{32} Bedeutet das…@d{96} du hast gewonnen?!\n$@c{smile_ehalf}Ich hätte wissen sollen, dass du es in dir hast.\n$@c{smile_eclosed}Natürlich… ich hatte immer dieses Gefühl.\n$@c{smile}Es ist jetzt vorbei, richtig? Du hast die Schleife beendet.\n$@c{smile_ehalf}Du hast auch deinen Traum erfüllt, nicht wahr?\n$Du hast nicht einmal verloren.\n$Ich werde die Einzige sein, die sich daran erinnert, was du getan hast.\n$@c{angry_mopen}Ich werde versuchen, es nicht zu vergessen!\n$@c{smile_wave_wink}Nur ein Scherz!@d{64} @c{smile}Ich würde es nie vergessen.@d{32}\n$Deine Legende wird in unseren Herzen weiterleben.\n$@c{smile_wave}Wie auch immer,@d{64} es wird spät…@d{96} denke ich?\nEs ist schwer zu sagen an diesem Ort.\n$Lass uns nach Hause gehen. \n$@c{smile_wave_wink}Vielleicht können wir morgen noch einen Kampf haben, der alten Zeiten willen?", "ending_female": "@c{smile}Oh? Du hast gewonnen?@d{96} @c{smile_eclosed}Ich schätze, das hätte ich wissen sollen.\n$Aber, du bist jetzt zurück.\n$@c{smile}Es ist vorbei.@d{64} Du hast die Schleife beendet.\n$@c{serious_smile_fists}Du hast auch deinen Traum erfüllt, nicht wahr?\nDu hast nicht einmal verloren.\n$@c{neutral}Ich bin der Einzige, der sich daran erinnern wird, was du getan hast.@d{96}\n$Ich schätze, das ist in Ordnung, oder?\n$@c{serious_smile_fists}Deine Legende wird immer in unseren Herzen weiterleben.\n$@c{smile_eclosed}Wie auch immer, ich habe genug von diesem Ort, oder nicht? Lass uns nach Hause gehen.\n$@c{serious_smile_fists}Vielleicht können wir, wenn wir zurück sind, noch einen Kampf haben?\n$Wenn du dazu bereit bist.",
"ending_endless": "Glückwunsch! Du hast das aktuelle Ende erreicht!\nWir arbeiten an mehr Spielinhalten.", "ending_endless": "Glückwunsch! Du hast das aktuelle Ende erreicht!\nWir arbeiten an mehr Spielinhalten.",
"ending_name": "Entwickler" "ending_name": "Entwickler"
} }

View File

@ -25,5 +25,6 @@
"unlinkGoogle": "Google trennen", "unlinkGoogle": "Google trennen",
"cancel": "Abbrechen", "cancel": "Abbrechen",
"losingProgressionWarning": "Du wirst jeglichen Fortschritt seit Anfang dieses Kampfes verlieren. Fortfahren?", "losingProgressionWarning": "Du wirst jeglichen Fortschritt seit Anfang dieses Kampfes verlieren. Fortfahren?",
"noEggs": "Du brütest aktuell keine Eier aus!" "noEggs": "Du brütest aktuell keine Eier aus!",
"donate": "Spenden"
} }

View File

@ -49,8 +49,8 @@
"DoubleBattleChanceBoosterModifierType": { "DoubleBattleChanceBoosterModifierType": {
"description": "Verdoppelt die Wahrscheinlichkeit, dass die nächsten {{battleCount}} Begegnungen mit wilden Pokémon ein Doppelkampf sind." "description": "Verdoppelt die Wahrscheinlichkeit, dass die nächsten {{battleCount}} Begegnungen mit wilden Pokémon ein Doppelkampf sind."
}, },
"TempBattleStatBoosterModifierType": { "TempStatStageBoosterModifierType": {
"description": "Erhöht die {{tempBattleStatName}} aller Teammitglieder für 5 Kämpfe um eine Stufe." "description": "Erhöht die {{stat}} aller Teammitglieder für 5 Kämpfe um eine Stufe."
}, },
"AttackTypeBoosterModifierType": { "AttackTypeBoosterModifierType": {
"description": "Erhöht die Stärke aller {{moveType}}-Attacken eines Pokémon um 20%." "description": "Erhöht die Stärke aller {{moveType}}-Attacken eines Pokémon um 20%."
@ -61,8 +61,8 @@
"AllPokemonLevelIncrementModifierType": { "AllPokemonLevelIncrementModifierType": {
"description": "Erhöht das Level aller Teammitglieder um {{levels}}." "description": "Erhöht das Level aller Teammitglieder um {{levels}}."
}, },
"PokemonBaseStatBoosterModifierType": { "BaseStatBoosterModifierType": {
"description": "Erhöht den {{statName}} Basiswert des Trägers um 10%. Das Stapellimit erhöht sich, je höher dein IS-Wert ist." "description": "Erhöht den {{stat}} Basiswert des Trägers um 10%. Das Stapellimit erhöht sich, je höher dein IS-Wert ist."
}, },
"AllPokemonFullHpRestoreModifierType": { "AllPokemonFullHpRestoreModifierType": {
"description": "Stellt 100% der KP aller Pokémon her." "description": "Stellt 100% der KP aller Pokémon her."
@ -248,6 +248,12 @@
"name": "Scope-Linse", "name": "Scope-Linse",
"description": "Ein Item zum Tragen. Es erhöht die Volltrefferquote." "description": "Ein Item zum Tragen. Es erhöht die Volltrefferquote."
}, },
"DIRE_HIT": {
"name": "X-Volltreffer",
"extra": {
"raises": "Volltrefferquote"
}
},
"LEEK": { "LEEK": {
"name": "Lauchstange", "name": "Lauchstange",
"description": "Ein Item, das von Porenta getragen werden kann. Diese lange Lauchstange erhöht die Volltrefferquote stark." "description": "Ein Item, das von Porenta getragen werden kann. Diese lange Lauchstange erhöht die Volltrefferquote stark."
@ -411,25 +417,13 @@
"description": "Ein Item, das Ditto zum Tragen gegeben werden kann. Fein und doch hart, erhöht dieses sonderbare Pulver die Initiative." "description": "Ein Item, das Ditto zum Tragen gegeben werden kann. Fein und doch hart, erhöht dieses sonderbare Pulver die Initiative."
} }
}, },
"TempBattleStatBoosterItem": { "TempStatStageBoosterItem": {
"x_attack": "X-Angriff", "x_attack": "X-Angriff",
"x_defense": "X-Verteidigung", "x_defense": "X-Verteidigung",
"x_sp_atk": "X-Sp.-Ang.", "x_sp_atk": "X-Sp.-Ang.",
"x_sp_def": "X-Sp.-Vert.", "x_sp_def": "X-Sp.-Vert.",
"x_speed": "X-Tempo", "x_speed": "X-Tempo",
"x_accuracy": "X-Treffer", "x_accuracy": "X-Treffer"
"dire_hit": "X-Volltreffer"
},
"TempBattleStatBoosterStatName": {
"ATK": "Angriff",
"DEF": "Verteidigung",
"SPATK": "Sp. Ang",
"SPDEF": "Sp. Vert",
"SPD": "Initiative",
"ACC": "Genauigkeit",
"CRIT": "Volltrefferquote",
"EVA": "Fluchtwert",
"DEFAULT": "???"
}, },
"AttackTypeBoosterItem": { "AttackTypeBoosterItem": {
"silk_scarf": "Seidenschal", "silk_scarf": "Seidenschal",
@ -606,4 +600,4 @@
"FAIRY_MEMORY": "Feen-Disc", "FAIRY_MEMORY": "Feen-Disc",
"NORMAL_MEMORY": "Normal-Disc" "NORMAL_MEMORY": "Normal-Disc"
} }
} }

View File

@ -3,7 +3,7 @@
"turnHealApply": "{{typeName}} von {{pokemonNameWithAffix}} füllt einige KP auf!", "turnHealApply": "{{typeName}} von {{pokemonNameWithAffix}} füllt einige KP auf!",
"hitHealApply": "{{typeName}} von {{pokemonNameWithAffix}} füllt einige KP auf!", "hitHealApply": "{{typeName}} von {{pokemonNameWithAffix}} füllt einige KP auf!",
"pokemonInstantReviveApply": "{{pokemonNameWithAffix}} wurde durch {{typeName}} wiederbelebt!", "pokemonInstantReviveApply": "{{pokemonNameWithAffix}} wurde durch {{typeName}} wiederbelebt!",
"pokemonResetNegativeStatStageApply": "Die negative Statuswertveränderung von {{pokemonNameWithAffix}} wurde durch {{typeName}} aufgehoben!", "resetNegativeStatStageApply": "Die negative Statuswertveränderung von {{pokemonNameWithAffix}} wurde durch {{typeName}} aufgehoben!",
"moneyInterestApply": "Du erhählst {{moneyAmount}} ₽ durch das Item {{typeName}}!", "moneyInterestApply": "Du erhählst {{moneyAmount}} ₽ durch das Item {{typeName}}!",
"turnHeldItemTransferApply": "{{itemName}} von {{pokemonNameWithAffix}} wurde durch {{typeName}} von {{pokemonName}} absorbiert!", "turnHeldItemTransferApply": "{{itemName}} von {{pokemonNameWithAffix}} wurde durch {{typeName}} von {{pokemonName}} absorbiert!",
"contactHeldItemTransferApply": "{{itemName}} von {{pokemonNameWithAffix}} wurde durch {{typeName}} von {{pokemonName}} geklaut!", "contactHeldItemTransferApply": "{{itemName}} von {{pokemonNameWithAffix}} wurde durch {{typeName}} von {{pokemonName}} geklaut!",

View File

@ -3,6 +3,10 @@
"cutHpPowerUpMove": "{{pokemonName}} nutzt seine KP um seine Attacke zu verstärken!", "cutHpPowerUpMove": "{{pokemonName}} nutzt seine KP um seine Attacke zu verstärken!",
"absorbedElectricity": "{{pokemonName}} absorbiert elektrische Energie!", "absorbedElectricity": "{{pokemonName}} absorbiert elektrische Energie!",
"switchedStatChanges": "{{pokemonName}} tauschte die Statuswerteveränderungen mit dem Ziel!", "switchedStatChanges": "{{pokemonName}} tauschte die Statuswerteveränderungen mit dem Ziel!",
"switchedTwoStatChanges": "{{pokemonName}} tauscht Veränderungen an {{firstStat}} und {{secondStat}} mit dem Ziel!",
"switchedStat": "{{pokemonName}} tauscht seinen {{stat}}-Wert mit dem des Zieles!",
"sharedGuard": "{{pokemonName}} addiert seine Schutzkräfte mit jenen des Zieles und teilt sie gerecht auf!",
"sharedPower": "{{pokemonName}} addiert seine Kräfte mit jenen des Zieles und teilt sie gerecht auf!",
"goingAllOutForAttack": "{{pokemonName}} legt sich ins Zeug!", "goingAllOutForAttack": "{{pokemonName}} legt sich ins Zeug!",
"regainedHealth": "{{pokemonName}} erholt sich!", "regainedHealth": "{{pokemonName}} erholt sich!",
"keptGoingAndCrashed": "{{pokemonName}} springt daneben und verletzt sich!", "keptGoingAndCrashed": "{{pokemonName}} springt daneben und verletzt sich!",
@ -63,4 +67,4 @@
"swapArenaTags": "{{pokemonName}} hat die Effekte, die auf den beiden Seiten des Kampffeldes wirken, miteinander getauscht!", "swapArenaTags": "{{pokemonName}} hat die Effekte, die auf den beiden Seiten des Kampffeldes wirken, miteinander getauscht!",
"exposedMove": "{{pokemonName}} erkennt {{targetPokemonName}}!", "exposedMove": "{{pokemonName}} erkennt {{targetPokemonName}}!",
"safeguard": "{{targetName}} wird durch Bodyguard geschützt!" "safeguard": "{{targetName}} wird durch Bodyguard geschützt!"
} }

View File

@ -1,7 +1,6 @@
{ {
"Stat": { "Stat": {
"HP": "KP", "HP": "KP",
"HPStat": "KP",
"HPshortened": "KP", "HPshortened": "KP",
"ATK": "Angriff", "ATK": "Angriff",
"ATKshortened": "Ang", "ATKshortened": "Ang",

View File

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

View File

@ -97,9 +97,9 @@
"name": "Master League Champion", "name": "Master League Champion",
"name_female": "Master League Champion" "name_female": "Master League Champion"
}, },
"TRANSFER_MAX_BATTLE_STAT": { "TRANSFER_MAX_STAT_STAGE": {
"name": "Teamwork", "name": "Teamwork",
"description": "Baton pass to another party member with at least one stat maxed out" "description": "Baton pass to another party member with at least one stat stage maxed out"
}, },
"MAX_FRIENDSHIP": { "MAX_FRIENDSHIP": {
"name": "Friendmaxxing", "name": "Friendmaxxing",
@ -284,4 +284,4 @@
"name": "Mirror rorriM", "name": "Mirror rorriM",
"description": "Complete the Inverse Battle challenge.\n.egnellahc elttaB esrevnI eht etelpmoC" "description": "Complete the Inverse Battle challenge.\n.egnellahc elttaB esrevnI eht etelpmoC"
} }
} }

View File

@ -61,6 +61,7 @@
"skipItemQuestion": "Are you sure you want to skip taking an item?", "skipItemQuestion": "Are you sure you want to skip taking an item?",
"itemStackFull": "The stack for {{fullItemName}} is full.\nYou will receive {{itemName}} instead.", "itemStackFull": "The stack for {{fullItemName}} is full.\nYou will receive {{itemName}} instead.",
"eggHatching": "Oh?", "eggHatching": "Oh?",
"eggSkipPrompt": "Skip to egg summary?",
"ivScannerUseQuestion": "Use IV Scanner on {{pokemonName}}?", "ivScannerUseQuestion": "Use IV Scanner on {{pokemonName}}?",
"wildPokemonWithAffix": "Wild {{pokemonName}}", "wildPokemonWithAffix": "Wild {{pokemonName}}",
"foePokemonWithAffix": "Foe {{pokemonName}}", "foePokemonWithAffix": "Foe {{pokemonName}}",

View File

@ -1,6 +1,6 @@
{ {
"ending": "@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": "@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{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_endless": "Congratulations on reaching the current end!\nMore content is coming soon.",
"ending_name": "Devs" "ending_name": "Devs"
} }

View File

@ -413,7 +413,7 @@
}, },
"ariana": { "ariana": {
"encounter": { "encounter": {
"1": "Hold it right there! We can't someone on the loose.\n$It's harmful to Team Rocket's pride, you see.", "1": "Hold it right there!\nWe can't have someone on the loose.\n$It's harmful to Team Rocket's pride, you see.",
"2": "I don't know or care if what I'm doing is right or wrong...\n$I just put my faith in Giovanni and do as I am told", "2": "I don't know or care if what I'm doing is right or wrong...\n$I just put my faith in Giovanni and do as I am told",
"3": "Your trip ends here. I'm going to take you down!" "3": "Your trip ends here. I'm going to take you down!"
}, },
@ -699,6 +699,7 @@
"encounter": { "encounter": {
"1": "I'll fight you with all I have to wipe you out!", "1": "I'll fight you with all I have to wipe you out!",
"2": "I don't care if you're a kid or what. I'll send you flying if you threaten us!", "2": "I don't care if you're a kid or what. I'll send you flying if you threaten us!",
"2_female": "I don't care if you're a kid or what. I'll send you flying if you threaten us!",
"3": "I was told to turn away Trainers, whomever they might be!", "3": "I was told to turn away Trainers, whomever they might be!",
"4": "I'll show you the power of Aether Paradise!", "4": "I'll show you the power of Aether Paradise!",
"5": "Now that you've learned of the darkness at the heart of Aether Paradise, we'll need you to conveniently disappear!" "5": "Now that you've learned of the darkness at the heart of Aether Paradise, we'll need you to conveniently disappear!"
@ -715,11 +716,13 @@
"encounter": { "encounter": {
"1": "I, Branch Chief Faba, shall show you the harshness of the real world!", "1": "I, Branch Chief Faba, shall show you the harshness of the real world!",
"2": "The man who is called Aether Paradise's last line of defense is to battle a mere child?", "2": "The man who is called Aether Paradise's last line of defense is to battle a mere child?",
"2_female": "The man who is called Aether Paradise's last line of defense is to battle a mere child?",
"3": "I, Faba, am the Aether Branch Chief. The only one in the world, I'm irreplaceable." "3": "I, Faba, am the Aether Branch Chief. The only one in the world, I'm irreplaceable."
}, },
"victory": { "victory": {
"1": "Aiyee!", "1": "Aiyee!",
"2": "H-h-how can this be?! How could this child...", "2": "H-h-how can this be?! How could this child...",
"2_female": "H-h-how can this be?! How could this child...",
"3": "This is why... This is why I can't bring myself to like children." "3": "This is why... This is why I can't bring myself to like children."
} }
}, },
@ -727,9 +730,12 @@
"encounter": { "encounter": {
"1": "We're not bad-we're just hard!", "1": "We're not bad-we're just hard!",
"2": "You want some? That's how we say hello! Nice knowing you, punks!", "2": "You want some? That's how we say hello! Nice knowing you, punks!",
"2_female": "You want some? That's how we say hello! Nice knowing you, punks!",
"3": "We're just a bunch of guys and gals with a great interest in other people's Pokémon!", "3": "We're just a bunch of guys and gals with a great interest in other people's Pokémon!",
"4": "Why you trying to act hard when we're already hard as bones out here, homie?", "4": "Why you trying to act hard when we're already hard as bones out here, homie?",
"5": "Team Skull represent! We can't pay the rent! Had a lot of fun, but our youth was misspent!" "4_female": "Why you trying to act hard when we're already hard as bones out here, homie?",
"5": "Team Skull represent! We can't pay the rent! Had a lot of fun, but our youth was misspent!",
"5_female": "Team Skull represent! We can't pay the rent! Had a lot of fun, but our youth was misspent!"
}, },
"victory": { "victory": {
"1": "Huh? Is it over already?", "1": "Huh? Is it over already?",
@ -742,11 +748,13 @@
"plumeria": { "plumeria": {
"encounter": { "encounter": {
"1": " ...Hmph. You don't look like anything special to me.", "1": " ...Hmph. You don't look like anything special to me.",
"1_female": " ...Hmph. You don't look like anything special to me.",
"2": "It takes these dumb Grunts way too long to deal with you kids...", "2": "It takes these dumb Grunts way too long to deal with you kids...",
"3": "Mess with anyone in Team Skull, and I'll show you how serious I can get." "3": "Mess with anyone in Team Skull, and I'll show you how serious I can get."
}, },
"victory": { "victory": {
"1": "Hmmph! You're pretty strong. I'll give you that.", "1": "Hmmph! You're pretty strong. I'll give you that.",
"1_female": "Hmmph! You're pretty strong. I'll give you that.",
"2": "Hmmph. Guess you are pretty tough. Now I understand why my Grunts waste so much time battling kids.", "2": "Hmmph. Guess you are pretty tough. Now I understand why my Grunts waste so much time battling kids.",
"3": "Hmmph! I guess I just have to hold that loss." "3": "Hmmph! I guess I just have to hold that loss."
} }
@ -755,6 +763,7 @@
"encounter": { "encounter": {
"1": "It looks like this is the end of the line for you!", "1": "It looks like this is the end of the line for you!",
"2": "You are a trainer aren't you? I'm afraid that doesn't give you the right to interfere in our work.", "2": "You are a trainer aren't you? I'm afraid that doesn't give you the right to interfere in our work.",
"2_female": "You are a trainer aren't you? I'm afraid that doesn't give you the right to interfere in our work.",
"3": "I'm from Macro Cosmos Insurance! Do you have a life insurance policy?" "3": "I'm from Macro Cosmos Insurance! Do you have a life insurance policy?"
}, },
"victory": { "victory": {
@ -772,6 +781,7 @@
"victory": { "victory": {
"1": "*sigh* I wasn't able to win... Oleana...you really are a hopeless woman.", "1": "*sigh* I wasn't able to win... Oleana...you really are a hopeless woman.",
"2": "Arghhh! This is inexcusable... What was I thinking... Any trainer who's made it this far would be no pushover..", "2": "Arghhh! This is inexcusable... What was I thinking... Any trainer who's made it this far would be no pushover..",
"2_female": "Arghhh! This is inexcusable... What was I thinking... Any trainer who's made it this far would be no pushover..",
"3": "*sigh* I am one tired Oleana..." "3": "*sigh* I am one tired Oleana..."
} }
}, },

View File

@ -24,6 +24,7 @@
"linkGoogle": "Link Google", "linkGoogle": "Link Google",
"unlinkGoogle": "Unlink Google", "unlinkGoogle": "Unlink Google",
"cancel": "Cancel", "cancel": "Cancel",
"donate": "Donate",
"losingProgressionWarning": "You will lose any progress since the beginning of the battle. Proceed?", "losingProgressionWarning": "You will lose any progress since the beginning of the battle. Proceed?",
"noEggs": "You are not hatching\nany eggs at the moment!" "noEggs": "You are not hatching\nany eggs at the moment!"
} }

View File

@ -49,8 +49,8 @@
"DoubleBattleChanceBoosterModifierType": { "DoubleBattleChanceBoosterModifierType": {
"description": "Doubles the chance of an encounter being a double battle for {{battleCount}} battles." "description": "Doubles the chance of an encounter being a double battle for {{battleCount}} battles."
}, },
"TempBattleStatBoosterModifierType": { "TempStatStageBoosterModifierType": {
"description": "Increases the {{tempBattleStatName}} of all party members by 1 stage for 5 battles." "description": "Increases the {{stat}} of all party members by 1 stage for 5 battles."
}, },
"AttackTypeBoosterModifierType": { "AttackTypeBoosterModifierType": {
"description": "Increases the power of a Pokémon's {{moveType}}-type moves by 20%." "description": "Increases the power of a Pokémon's {{moveType}}-type moves by 20%."
@ -61,8 +61,8 @@
"AllPokemonLevelIncrementModifierType": { "AllPokemonLevelIncrementModifierType": {
"description": "Increases all party members' level by {{levels}}." "description": "Increases all party members' level by {{levels}}."
}, },
"PokemonBaseStatBoosterModifierType": { "BaseStatBoosterModifierType": {
"description": "Increases the holder's base {{statName}} by 10%. The higher your IVs, the higher the stack limit." "description": "Increases the holder's base {{stat}} by 10%. The higher your IVs, the higher the stack limit."
}, },
"AllPokemonFullHpRestoreModifierType": { "AllPokemonFullHpRestoreModifierType": {
"description": "Restores 100% HP for all Pokémon." "description": "Restores 100% HP for all Pokémon."
@ -183,6 +183,7 @@
"SOOTHE_BELL": { "name": "Soothe Bell" }, "SOOTHE_BELL": { "name": "Soothe Bell" },
"SCOPE_LENS": { "name": "Scope Lens", "description": "It's a lens for scoping out weak points. It boosts the holder's critical-hit ratio."}, "SCOPE_LENS": { "name": "Scope Lens", "description": "It's a lens for scoping out weak points. It boosts the holder's critical-hit ratio."},
"DIRE_HIT": { "name": "Dire Hit", "extra": { "raises": "Critical Hit Ratio" } },
"LEEK": { "name": "Leek", "description": "This very long and stiff stalk of leek boosts the critical-hit ratio of Farfetch'd's moves."}, "LEEK": { "name": "Leek", "description": "This very long and stiff stalk of leek boosts the critical-hit ratio of Farfetch'd's moves."},
"EVIOLITE": { "name": "Eviolite", "description": "This mysterious evolutionary lump boosts the Defense and Sp. Def stats when held by a Pokémon that can still evolve." }, "EVIOLITE": { "name": "Eviolite", "description": "This mysterious evolutionary lump boosts the Defense and Sp. Def stats when held by a Pokémon that can still evolve." },
@ -250,28 +251,14 @@
"METAL_POWDER": { "name": "Metal Powder", "description": "Extremely fine yet hard, this odd powder boosts Ditto's Defense stat." }, "METAL_POWDER": { "name": "Metal Powder", "description": "Extremely fine yet hard, this odd powder boosts Ditto's Defense stat." },
"QUICK_POWDER": { "name": "Quick Powder", "description": "Extremely fine yet hard, this odd powder boosts Ditto's Speed stat." } "QUICK_POWDER": { "name": "Quick Powder", "description": "Extremely fine yet hard, this odd powder boosts Ditto's Speed stat." }
}, },
"TempBattleStatBoosterItem": { "TempStatStageBoosterItem": {
"x_attack": "X Attack", "x_attack": "X Attack",
"x_defense": "X Defense", "x_defense": "X Defense",
"x_sp_atk": "X Sp. Atk", "x_sp_atk": "X Sp. Atk",
"x_sp_def": "X Sp. Def", "x_sp_def": "X Sp. Def",
"x_speed": "X Speed", "x_speed": "X Speed",
"x_accuracy": "X Accuracy", "x_accuracy": "X Accuracy"
"dire_hit": "Dire Hit"
}, },
"TempBattleStatBoosterStatName": {
"ATK": "Attack",
"DEF": "Defense",
"SPATK": "Sp. Atk",
"SPDEF": "Sp. Def",
"SPD": "Speed",
"ACC": "Accuracy",
"CRIT": "Critical Hit Ratio",
"EVA": "Evasiveness",
"DEFAULT": "???"
},
"AttackTypeBoosterItem": { "AttackTypeBoosterItem": {
"silk_scarf": "Silk Scarf", "silk_scarf": "Silk Scarf",
"black_belt": "Black Belt", "black_belt": "Black Belt",

View File

@ -3,7 +3,7 @@
"turnHealApply": "{{pokemonNameWithAffix}} restored a little HP using\nits {{typeName}}!", "turnHealApply": "{{pokemonNameWithAffix}} restored a little HP using\nits {{typeName}}!",
"hitHealApply": "{{pokemonNameWithAffix}} restored a little HP using\nits {{typeName}}!", "hitHealApply": "{{pokemonNameWithAffix}} restored a little HP using\nits {{typeName}}!",
"pokemonInstantReviveApply": "{{pokemonNameWithAffix}} was revived\nby its {{typeName}}!", "pokemonInstantReviveApply": "{{pokemonNameWithAffix}} was revived\nby its {{typeName}}!",
"pokemonResetNegativeStatStageApply": "{{pokemonNameWithAffix}}'s lowered stats were restored\nby its {{typeName}}!", "resetNegativeStatStageApply": "{{pokemonNameWithAffix}}'s lowered stats were restored\nby its {{typeName}}!",
"moneyInterestApply": "You received interest of ₽{{moneyAmount}}\nfrom the {{typeName}}!", "moneyInterestApply": "You received interest of ₽{{moneyAmount}}\nfrom the {{typeName}}!",
"turnHeldItemTransferApply": "{{pokemonNameWithAffix}}'s {{itemName}} was absorbed\nby {{pokemonName}}'s {{typeName}}!", "turnHeldItemTransferApply": "{{pokemonNameWithAffix}}'s {{itemName}} was absorbed\nby {{pokemonName}}'s {{typeName}}!",
"contactHeldItemTransferApply": "{{pokemonNameWithAffix}}'s {{itemName}} was snatched\nby {{pokemonName}}'s {{typeName}}!", "contactHeldItemTransferApply": "{{pokemonNameWithAffix}}'s {{itemName}} was snatched\nby {{pokemonName}}'s {{typeName}}!",

View File

@ -3,6 +3,10 @@
"cutHpPowerUpMove": "{{pokemonName}} cut its own HP to power up its move!", "cutHpPowerUpMove": "{{pokemonName}} cut its own HP to power up its move!",
"absorbedElectricity": "{{pokemonName}} absorbed electricity!", "absorbedElectricity": "{{pokemonName}} absorbed electricity!",
"switchedStatChanges": "{{pokemonName}} switched stat changes with the target!", "switchedStatChanges": "{{pokemonName}} switched stat changes with the target!",
"switchedTwoStatChanges": "{{pokemonName}} switched all changes to its {{firstStat}}\nand {{secondStat}} with its target!",
"switchedStat": "{{pokemonName}} switched {{stat}} with its target!",
"sharedGuard": "{{pokemonName}} shared its guard with the target!",
"sharedPower": "{{pokemonName}} shared its power with the target!",
"goingAllOutForAttack": "{{pokemonName}} is going all out for this attack!", "goingAllOutForAttack": "{{pokemonName}} is going all out for this attack!",
"regainedHealth": "{{pokemonName}} regained\nhealth!", "regainedHealth": "{{pokemonName}} regained\nhealth!",
"keptGoingAndCrashed": "{{pokemonName}} kept going\nand crashed!", "keptGoingAndCrashed": "{{pokemonName}} kept going\nand crashed!",

View File

@ -1,7 +1,7 @@
{ {
"Stat": { "Stat": {
"HP": "Max. HP", "HP": "Max. HP",
"HPshortened": "MaxHP", "HPshortened": "HP",
"ATK": "Attack", "ATK": "Attack",
"ATKshortened": "Atk", "ATKshortened": "Atk",
"DEF": "Defense", "DEF": "Defense",
@ -13,8 +13,7 @@
"SPD": "Speed", "SPD": "Speed",
"SPDshortened": "Spd", "SPDshortened": "Spd",
"ACC": "Accuracy", "ACC": "Accuracy",
"EVA": "Evasiveness", "EVA": "Evasiveness"
"HPStat": "HP"
}, },
"Type": { "Type": {
"UNKNOWN": "Unknown", "UNKNOWN": "Unknown",
@ -38,4 +37,4 @@
"FAIRY": "Fairy", "FAIRY": "Fairy",
"STELLAR": "Stellar" "STELLAR": "Stellar"
} }
} }

View File

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

View File

@ -91,7 +91,7 @@
"name": "Campeón Liga Master", "name": "Campeón Liga Master",
"name_female": "Campeona Liga Master" "name_female": "Campeona Liga Master"
}, },
"TRANSFER_MAX_BATTLE_STAT": { "TRANSFER_MAX_STAT_STAGE": {
"name": "Trabajo en Equipo", "name": "Trabajo en Equipo",
"description": "Haz relevo a otro miembro del equipo con al menos una estadística al máximo." "description": "Haz relevo a otro miembro del equipo con al menos una estadística al máximo."
}, },
@ -175,4 +175,4 @@
"name": "Espejo ojepsE", "name": "Espejo ojepsE",
"description": "Completa el reto de Combate Inverso.\n.osrevnI etabmoC ed oter le atelpmoC" "description": "Completa el reto de Combate Inverso.\n.osrevnI etabmoC ed oter le atelpmoC"
} }
} }

View File

@ -1,21 +1,21 @@
{ {
"activeBattleEffects": "Efectos de Terreno Activos", "activeBattleEffects": "Efectos de terreno activos",
"player": "Jugador", "player": "Jugador",
"neutral": "Neutral", "neutral": "Neutral",
"enemy": "Enemigo", "enemy": "Enemigo",
"sunny": "Sol", "sunny": "Sol",
"rain": "Lluvia", "rain": "Lluvia",
"sandstorm": "Tormenta de Arena", "sandstorm": "Tormenta de arena",
"hail": "Granizo", "hail": "Granizo",
"snow": "Nieve", "snow": "Nieve",
"fog": "Niebla", "fog": "Niebla",
"heavyRain": "Diluvio", "heavyRain": "Diluvio",
"harshSun": "Sol Abrasador", "harshSun": "Sol abrasador",
"strongWinds": "Turbulencias", "strongWinds": "Turbulencias",
"misty": "Campo de Niebla", "misty": "Campo de niebla",
"electric": "Campo Eléctrico", "electric": "Campo eléctrico",
"grassy": "Campo de Hierba", "grassy": "Campo de hierba",
"psychic": "Campo Psíquico", "psychic": "Campo psíquico",
"mudSport": "Chapoteo Lodo", "mudSport": "Chapoteo Lodo",
"waterSport": "Hidrochorro", "waterSport": "Hidrochorro",
"spikes": "Púas", "spikes": "Púas",
@ -37,4 +37,4 @@
"craftyShield": "Truco Defensa", "craftyShield": "Truco Defensa",
"tailwind": "Viento Afín", "tailwind": "Viento Afín",
"happyHour": "Paga Extra" "happyHour": "Paga Extra"
} }

View File

@ -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!", "safeguardOnAdd": "¡Todos los Pokémon están protegidos por Velo Sagrado!",
"safeguardOnAddPlayer": "¡Tu equipo se ha protegido con Velo Sagrado!", "safeguardOnAddPlayer": "¡Tu equipo se ha protegido con Velo Sagrado!",
"safeguardOnAddEnemy": "¡El equipo enemigo se ha protegido con Velo Sagrado!", "safeguardOnAddEnemy": "¡El equipo enemigo se ha protegido con Velo Sagrado!",

View File

@ -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!"
}

View File

@ -1,8 +1,8 @@
{ {
"classic": "Clásica", "classic": "Clásico",
"endless": "Infinita", "endless": "Infinito",
"endlessSpliced": "Infinita (Fusión)", "endlessSpliced": "Infinito (Fusión)",
"dailyRun": "Diaria", "dailyRun": "Diario",
"unknown": "Desconicido", "unknown": "Desconocido",
"challenge": "Desafío" "challenge": "Desafío"
} }

View File

@ -49,8 +49,8 @@
"DoubleBattleChanceBoosterModifierType": { "DoubleBattleChanceBoosterModifierType": {
"description": "Duplica la posibilidad de que un encuentro sea una combate doble durante {{battleCount}} combates." "description": "Duplica la posibilidad de que un encuentro sea una combate doble durante {{battleCount}} combates."
}, },
"TempBattleStatBoosterModifierType": { "TempStatStageBoosterModifierType": {
"description": "Aumenta la est. {{tempBattleStatName}} de todos los miembros del equipo en 1 nivel durante 5 combates." "description": "Aumenta la est. {{stat}} de todos los miembros del equipo en 1 nivel durante 5 combates."
}, },
"AttackTypeBoosterModifierType": { "AttackTypeBoosterModifierType": {
"description": "Aumenta la potencia de los movimientos de tipo {{moveType}} de un Pokémon en un 20%." "description": "Aumenta la potencia de los movimientos de tipo {{moveType}} de un Pokémon en un 20%."
@ -61,8 +61,8 @@
"AllPokemonLevelIncrementModifierType": { "AllPokemonLevelIncrementModifierType": {
"description": "Aumenta el nivel de todos los miembros del equipo en {{levels}}." "description": "Aumenta el nivel de todos los miembros del equipo en {{levels}}."
}, },
"PokemonBaseStatBoosterModifierType": { "BaseStatBoosterModifierType": {
"description": "Aumenta la est. {{statName}} base del portador en un 10%.\nCuanto mayores sean tus IVs, mayor será el límite de acumulación." "description": "Aumenta la est. {{stat}} base del portador en un 10%.\nCuanto mayores sean tus IVs, mayor será el límite de acumulación."
}, },
"AllPokemonFullHpRestoreModifierType": { "AllPokemonFullHpRestoreModifierType": {
"description": "Restaura el 100% de los PS de todos los Pokémon." "description": "Restaura el 100% de los PS de todos los Pokémon."
@ -248,6 +248,12 @@
"name": "Periscopio", "name": "Periscopio",
"description": "Aumenta la probabilidad de asestar un golpe crítico." "description": "Aumenta la probabilidad de asestar un golpe crítico."
}, },
"DIRE_HIT": {
"name": "Crítico X",
"extra": {
"raises": "Critical Hit Ratio"
}
},
"LEEK": { "LEEK": {
"name": "Puerro", "name": "Puerro",
"description": "Puerro muy largo y duro que aumenta la probabilidad de asestar un golpe crítico. Debe llevarlo Farfetch'd." "description": "Puerro muy largo y duro que aumenta la probabilidad de asestar un golpe crítico. Debe llevarlo Farfetch'd."
@ -411,25 +417,13 @@
"description": "Polvo muy fino, pero a la vez poderoso, que aumenta la Velocidad. Debe llevarlo Ditto." "description": "Polvo muy fino, pero a la vez poderoso, que aumenta la Velocidad. Debe llevarlo Ditto."
} }
}, },
"TempBattleStatBoosterItem": { "TempStatStageBoosterItem": {
"x_attack": "Ataque X", "x_attack": "Ataque X",
"x_defense": "Defensa X", "x_defense": "Defensa X",
"x_sp_atk": "Ataq. Esp. X", "x_sp_atk": "Ataq. Esp. X",
"x_sp_def": "Def. Esp. X", "x_sp_def": "Def. Esp. X",
"x_speed": "Velocidad X", "x_speed": "Velocidad X",
"x_accuracy": "Precisión X", "x_accuracy": "Precisión X"
"dire_hit": "Crítico X"
},
"TempBattleStatBoosterStatName": {
"ATK": "Ataque",
"DEF": "Defensa",
"SPATK": "Ataq. Esp.",
"SPDEF": "Def. Esp.",
"SPD": "Velocidad",
"ACC": "Precisión",
"CRIT": "Tasa de crítico",
"EVA": "Evasión",
"DEFAULT": "???"
}, },
"AttackTypeBoosterItem": { "AttackTypeBoosterItem": {
"silk_scarf": "Pañuelo seda", "silk_scarf": "Pañuelo seda",

View File

@ -1,4 +1,8 @@
{ {
"switchedTwoStatChanges": "{{pokemonName}} ha intercambiado los cambios en {{firstStat}} y {{secondStat}} con los del objetivo!",
"switchedStat": "{{pokemonName}} cambia su {{stat}} por la de su objetivo!",
"sharedGuard": "{{pokemonName}} suma su capacidad defensiva a la del objetivo y la reparte equitativamente!",
"sharedPower": "{{pokemonName}} suma su capacidad ofensiva a la del objetivo y la reparte equitativamente!",
"isChargingPower": "¡{{pokemonName}} está acumulando energía!", "isChargingPower": "¡{{pokemonName}} está acumulando energía!",
"burnedItselfOut": "¡El fuego interior de {{pokemonName}} se ha extinguido!", "burnedItselfOut": "¡El fuego interior de {{pokemonName}} se ha extinguido!",
"startedHeatingUpBeak": "¡{{pokemonName}} empieza\na calentar su pico!", "startedHeatingUpBeak": "¡{{pokemonName}} empieza\na calentar su pico!",
@ -9,4 +13,4 @@
"statEliminated": "¡Los cambios en estadísticas fueron eliminados!", "statEliminated": "¡Los cambios en estadísticas fueron eliminados!",
"revivalBlessing": "¡{{pokemonName}} ha revivido!", "revivalBlessing": "¡{{pokemonName}} ha revivido!",
"safeguard": "¡{{targetName}} está protegido por Velo Sagrado!" "safeguard": "¡{{targetName}} está protegido por Velo Sagrado!"
} }

View File

@ -1,4 +1,9 @@
{ {
"SEND_OUT": "Enviar",
"SUMMARY": "Resumen",
"CANCEL": "Cancelar",
"RELEASE": "Liberar",
"APPLY": "Aplicar",
"TEACH": "Enseñar", "TEACH": "Enseñar",
"SPLICE": "Fusionar", "SPLICE": "Fusionar",
"UNSPLICE": "Separar", "UNSPLICE": "Separar",
@ -7,23 +12,23 @@
"TRANSFER": "Transferir", "TRANSFER": "Transferir",
"ALL": "Todo", "ALL": "Todo",
"PASS_BATON": "Relevo", "PASS_BATON": "Relevo",
"UNPAUSE_EVOLUTION": "Reanudar Evolución", "UNPAUSE_EVOLUTION": "Reanudar evolución",
"REVIVE": "Revivir", "REVIVE": "Revivir",
"RENAME": "Rename", "RENAME": "Rename",
"choosePokemon": "Elige a un Pokémon.", "choosePokemon": "Elige a un Pokémon.",
"doWhatWithThisPokemon": "¿Que quieres hacer con este Pokémon?", "doWhatWithThisPokemon": "¿Que quieres hacer con este Pokémon?",
"noEnergy": "¡A {{pokemonName}} no le quedan\nfuerzas para luchar!", "noEnergy": "¡A {{pokemonName}} no le\nquedan fuerzas para luchar!",
"hasEnergy": "¡A {{pokemonName}} le quedan\nfuerzas para luchar!", "hasEnergy": "¡A {{pokemonName}} le\nquedan fuerzas para luchar!",
"cantBeUsed": "¡{{pokemonName}} no puede usarse\nen este desafío!", "cantBeUsed": "¡{{pokemonName}} no puede usarse en este desafío!",
"tooManyItems": "¡{{pokemonName}} tiene demasiados\nde este objeto!", "tooManyItems": "¡{{pokemonName}} tiene\ndemasiado de este objeto!",
"anyEffect": "No tendría ningún efecto.", "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á.", "unspliceConfirmation": "¿Seguro que quiere separar a {{fusionName}}\nde {{pokemonName}}? {{fusionName}} se perderá.",
"wasReverted": "{{fusionName}} se revirtió a {{pokemonName}}.", "wasReverted": "{{fusionName}} se revirtió a {{pokemonName}}.",
"releaseConfirmation": "¿Quieres liberar a {{pokemonName}}?", "releaseConfirmation": "¿Quieres liberar a {{pokemonName}}?",
"releaseInBattle": "¡No puedes liberar un Pokémon que está en batalla!", "releaseInBattle": "¡No puedes liberar un Pokémon que está en batalla!",
"selectAMove": "Selecciona un movimiento.", "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.", "selectAnotherPokemonToSplice": "Selecciona otro Pokémon para fusionar.",
"cancel": "Salir", "cancel": "Salir",
"able": "Apto", "able": "Apto",
@ -36,7 +41,7 @@
"thisIsWhereWePart": "¡Aquí es donde nos despedimos, {{pokemonName}}!", "thisIsWhereWePart": "¡Aquí es donde nos despedimos, {{pokemonName}}!",
"illMissYou": "¡Te echaré de menos, {{pokemonName}}!", "illMissYou": "¡Te echaré de menos, {{pokemonName}}!",
"illNeverForgetYou": "¡Nunca te olvidaré, {{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}}!", "sayonara": "¡Sayonara, {{pokemonName}}!",
"smellYaLater": "¡Nos vemos luego, {{pokemonName}}!" "smellYaLater": "¡Nos vemos luego, {{pokemonName}}!"
} }

View File

@ -10,5 +10,5 @@
"eternamaxChange": "¡{{preName}} ha eternamaxizado a {{pokemonName}}!", "eternamaxChange": "¡{{preName}} ha eternamaxizado a {{pokemonName}}!",
"revertChange": "¡{{pokemonName}} ha revertido a su forma original!", "revertChange": "¡{{pokemonName}} ha revertido a su forma original!",
"formChange": "¡{{preName}} ha cambiado de forma!", "formChange": "¡{{preName}} ha cambiado de forma!",
"disguiseChange": "¡El disfraz ha actuado como señuelo!\t" "disguiseChange": "¡El disfraz ha actuado como señuelo!"
} }

View File

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

View File

@ -92,7 +92,7 @@
"name": "Master Maitre de la Ligue", "name": "Master Maitre de la Ligue",
"name_female": "Master Maitresse de la Ligue" "name_female": "Master Maitresse de la Ligue"
}, },
"TRANSFER_MAX_BATTLE_STAT": { "TRANSFER_MAX_STAT_STAGE": {
"name": "Travail déquipe", "name": "Travail déquipe",
"description": "Utiliser Relais avec au moins une statistique montée à fond." "description": "Utiliser Relais avec au moins une statistique montée à fond."
}, },

View File

@ -94,5 +94,6 @@
"retryBattle": "Voulez-vous réessayer depuis le début du combat ?", "retryBattle": "Voulez-vous réessayer depuis le début du combat ?",
"unlockedSomething": "{{unlockedThing}}\na été débloqué.", "unlockedSomething": "{{unlockedThing}}\na été débloqué.",
"congratulations": "Félicitations !", "congratulations": "Félicitations !",
"beatModeFirstTime": "{{speciesName}} a battu le mode {{gameMode}} pour la première fois !\nVous avez reçu {{newModifier}} !" "beatModeFirstTime": "{{speciesName}} a battu le mode {{gameMode}} pour la première fois !\nVous avez reçu {{newModifier}} !",
} "eggSkipPrompt": "Aller directement au résumé des Œufs éclos ?"
}

View File

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

View File

@ -9,7 +9,7 @@
"6": "Allez, cest parti !", "6": "Allez, cest parti !",
"7": "Attention, me voilà !\nTu vas voir comment jsuis fort !", "7": "Attention, me voilà !\nTu vas voir comment jsuis fort !",
"8": "Coucou… Tu veux voir mes bô Pokémon ?", "8": "Coucou… Tu veux voir mes bô Pokémon ?",
"9": "Trève de mondanités. Ramène-toi quand tu le sens !", "9": "Trêve de mondanités. Ramène-toi quand tu le sens !",
"10": "Baisse pas ta garde si tu veux pas pleurer davoir perdu face à un gamin.", "10": "Baisse pas ta garde si tu veux pas pleurer davoir perdu face à un gamin.",
"11": "Jai tout donné pour élever mes Pokémon. Attention à toi si tu leur fait du mal !", "11": "Jai tout donné pour élever mes Pokémon. Attention à toi si tu leur fait du mal !",
"12": "Incroyable que ty sois parvenu ! Mais la suite va pas être une partie de plaisir.", "12": "Incroyable que ty sois parvenu ! Mais la suite va pas être une partie de plaisir.",
@ -68,7 +68,7 @@
"3": "Hum, tes pas trop laxiste avec tes Pokémon ?\nTrop les chouchouter nest pas bon." "3": "Hum, tes pas trop laxiste avec tes Pokémon ?\nTrop les chouchouter nest pas bon."
}, },
"victory": { "victory": {
"1": "Il est primordial de nourir et développer toutes les caractéristiques de chaque Pokémon.", "1": "Il est primordial de nourrir et développer toutes les caractéristiques de chaque Pokémon.",
"2": "Contrairement à moi, ces Pokémon ont un bon fond.", "2": "Contrairement à moi, ces Pokémon ont un bon fond.",
"3": "Trop déloges peut ruiner les Pokémon et les gens." "3": "Trop déloges peut ruiner les Pokémon et les gens."
}, },
@ -229,7 +229,7 @@
"encounter": { "encounter": {
"1": "Ne te mets pas en travers de la Team Galaxie !", "1": "Ne te mets pas en travers de la Team Galaxie !",
"2": "Sois témoin de la puissance de notre technologie et du futur qui se profile !", "2": "Sois témoin de la puissance de notre technologie et du futur qui se profile !",
"3": "Au nom de la Team Galaxie, jéliminerai quiconque se mettera sur notre route !", "3": "Au nom de la Team Galaxie, jéliminerai quiconque se mettra sur notre route !",
"4": "Prépare ta défaite !", "4": "Prépare ta défaite !",
"5": "Jespère que tes prêt à te prendre une raclée de lespace !", "5": "Jespère que tes prêt à te prendre une raclée de lespace !",
"5_female": "Jespère que tes prête à te prendre une raclée de lespace !" "5_female": "Jespère que tes prête à te prendre une raclée de lespace !"
@ -244,7 +244,7 @@
}, },
"plasma_grunt": { "plasma_grunt": {
"encounter": { "encounter": {
"1": "Pas de quatiers à ceux qui ne suivent pas notre idéal !", "1": "Pas de quartiers à quiconque ne suit pas notre idéal !",
"2": "Si je gagne, tu relâches tous tes Pokémon !", "2": "Si je gagne, tu relâches tous tes Pokémon !",
"3": "Si tu te mets en travers de la Team Plasma, je moccuperai de toi personnellement !", "3": "Si tu te mets en travers de la Team Plasma, je moccuperai de toi personnellement !",
"4": "La Team Plasma va libérer les Pokémon de tous les humains égoïstes dans ton genre !", "4": "La Team Plasma va libérer les Pokémon de tous les humains égoïstes dans ton genre !",
@ -275,6 +275,96 @@
"5": "Jappelle pas ça perdre, jappelle ça échouer avec panache !" "5": "Jappelle pas ça perdre, jappelle ça échouer avec panache !"
} }
}, },
"aether_grunt": {
"encounter": {
"1": "Je vais te mettre ta raclée !",
"2": "Jen ai rien à faire que tu sois une gosse. Tu vas tutoyer les étoiles si tu nous menaces !",
"2_female": "Jen ai rien à faire que tu sois une gosse. Tu vas tutoyer les étoiles si tu nous menaces !",
"3": "Jai pour ordre de ne laisser passer aucun Dresseur, peu importe qui cest !",
"4": "Je vais te montrer le pouvoir du Paradis Æther !",
"5": "Maintenant que tes au courant de ce quil se passe au cœur du Paradis Æther, fais-moi une faveur et disparait !"
},
"victory": {
"1": "Cest plutôt toi qui devrait mapprendre à en mettre…",
"2": "Pardon ? Jai pas compris…",
"3": "Peu importe les ordres, jamais jaurais pu te retenir en fait…",
"4": "Mhh… Il semblerait que jai perdu.",
"5": "Cest plutôt moi qui va disparaitre je crois."
}
},
"faba": {
"encounter": {
"1": "Moi, Directeur Saubohne, je vais te montrer de quel bois je me chauffe !",
"2": "Donc là, lhomme supposé être la dernière ligne défense du Paradis Æther doit affronter un mioche ?",
"2_female": "Donc là, lhomme supposé être la dernière ligne défense du Paradis Æther doit affronter un mioche ?",
"3": "Sil ny a quun seul nom à retenir au sein de la Fondation Æther, cest le mien : Saubohne !"
},
"victory": {
"1": "Gloups !",
"2": "Malheur ! Jai perdu face à un simple enfant ?!",
"2_female": "Malheur ! Jai perdu face à une simple enfant ?!",
"3": "Jai HORREUR des enfants !"
}
},
"skull_grunt": {
"encounter": {
"1": "Oush oush ! On est pas méchants, sauf si tu viens nous allumer la mèche-han !",
"2": "Ce manque de respect, jhallucine ! Tes allé trop loin, le mioche !",
"2_female": "Ce manque de respect, jhallucine ! Tes allée trop loin, la mioche !",
"3": "On est juste des gars et des meufs normaux, on voit un Pokémon on le prend !",
"4": "Pourquoi tu te la joue comme ça ? C'est avec tes dents que tvas jouer frérot.",
"4_female": "Pourquoi tu te la joue comme ça ? C'est avec tes dents que tvas jouer ma reus.",
"5": "Cousin, écoute-nous bien ! ♪\nSe taper dessus, ça sert à rien ! ♪\n$Tu tincrustes chez nous, ça sfait pas ! ♪\n$Mais on est sympa, on a un plan pour toi ! ♪",
"5_female": "Cousine, écoute-nous bien ! ♪\nSe taper dessus, ça sert à rien ! ♪\n$Tu tincrustes chez nous, ça sfait pas ! ♪\n$Mais on est sympa, on a un plan pour toi ! ♪"
},
"victory": {
"1": "Hein ? Cest déjà terminé ?",
"2": "… Ça craint grave! On stire!",
"3": "Ouais de toute on en avait pas bsoin de ton Pokémon… Ah ah…",
"4": "Ouh là, cest bon, jen demandais pas tant…",
"5": "On pèse plus que des Pokémon, tentends ?\nAlors tu vas nous respecter, oush !"
}
},
"plumeria": {
"encounter": {
"1": "Tsk. Tes un gamin tout ce quil y a de plus banal, en fait.",
"1_female": "Tsk. Tes une gamine tout ce quil y a de plus banal, en fait.",
"2": "Abrutis de sbires. Trop incompétents pour arriver à se débarasser de gamins…",
"3": "Si tu touches encore à un cheveu de mes lascars, tu vas pas comprendre cqui tarrive !"
},
"victory": {
"1": "Tsk. Tes pas mauvais. Jte laccorde.",
"1_female": "Tsk. Tes pas mauvaise. Jte laccorde.",
"2": "Tsk. Jdois reconnaitre que ten as dans le ventre.\n$Maintenant, jcomprends pourquoi mes gars narrêtent pas de se faire battre par toi.",
"3": "Tsk. Jcrois que j'ai plus quà assumer ma défaite."
}
},
"macro_grunt": {
"encounter": {
"1": "Hop hop hop ! Terminus !",
"2": "Tes un Dresseur nest-ce pas ?\n$Jai bien peur ce que ne soit pas une excuse suffisante pour nous interrompre dans notre travail.",
"2_female": "Tes une Dresseuse nest-ce pas ?\n$Jai bien peur ce que ne soit pas une excuse suffisante pour nous interrompre dans notre travail.",
"3": "Je travaille à Macro Cosmos Assurances !\nBesoin dune assurance-vie ?"
},
"victory": {
"1": "Je nai dautre choix que respectueusement me retirer.",
"2": "Mon argent de poche…\nPlus quà manger des pâtes pour la fin du mois…",
"3": "Chez Macro Cosmos, rien nest comparable à notre dévotion au travail !"
}
},
"oleana": {
"encounter": {
"1": "Je ne laisserai personne interférer avec les projets du président Shehroz.",
"2": "Je vois que vous avez su vous défaire de mes subalternes.\n$Mais assez joué. Il est temps de rentrer chez vous, maintenant.",
"3": "Je gagnerai en votre nom, monsieur le président."
},
"victory": {
"1": "*soupir* Comment ai-je fait pour perdre ainsi…?\nJe ne suis vraiment pas à la hauteur…",
"2": "Ah! Quelle erreur… Je naurais pas dû sous-estimer un Dresseur de ton calibre…",
"2_female": "Ah! Quelle erreur… Je naurais pas dû sous-estimer une Dresseuse de ton calibre…",
"3": "*soupir* Je suis fatiguée parton…"
}
},
"rocket_boss_giovanni_1": { "rocket_boss_giovanni_1": {
"encounter": { "encounter": {
"1": "Bien. Je dois admettre que je suis impressionné de te voir ici !" "1": "Bien. Je dois admettre que je suis impressionné de te voir ici !"
@ -468,7 +558,7 @@
"4": "Voir un tel jardin rempli de fleurs est si apaisant…" "4": "Voir un tel jardin rempli de fleurs est si apaisant…"
}, },
"victory": { "victory": {
"1": "Bien joué, cest mértié.", "1": "Bien joué, cest mérité.",
"2": "Dommage, on samusait si bien…", "2": "Dommage, on samusait si bien…",
"3": "Oh non, le combat est terminé…", "3": "Oh non, le combat est terminé…",
"4": "Aaah, ça fait du bien !\nMerci, jen avais besoin." "4": "Aaah, ça fait du bien !\nMerci, jen avais besoin."
@ -505,15 +595,15 @@
}, },
"rival": { "rival": {
"encounter": { "encounter": {
"1": "@c{smile}Ah, je te cherchais ! Je savais que tétais pressé de partir, mais je mattendais quand même à un au revoir…\n$@c{smile_eclosed}Tas finalement décidé de réaliser ton rêve ?\nJai peine à y croire.\n$@c{serious_smile_fists}Vu que tes là, ça te dis un petit combat ?\nJe voudrais quand même massurer que tes prêt.\n$@c{serious_mopen_fists}Surtout ne te retiens pas et donne-moi tout ce que tas !" "1": "@c{smile}Ah, je te cherchais ! Je savais que tétais pressée de partir, mais je mattendais quand même à un au revoir…\n$@c{smile_eclosed}Tas finalement décidé de réaliser ton rêve ?\nJai peine à y croire.\n$@c{serious_smile_fists}Vu que tes là, ça te dis un petit combat ?\nJe voudrais quand même massurer que tes prête.\n$@c{serious_mopen_fists}Surtout ne te retiens pas et donne-moi tout ce que tas !"
}, },
"victory": { "victory": {
"1": "@c{shock}Wah… Tu mas vraiment lavé.\nTes vraiment un débutant ?\n$@c{smile}Tas peut-être eu de la chance, mais…\nPeut-être que tarriveras jusquau bout du chemin.\n$Dailleurs, le prof ma demandé de te filer ces objets.\nIls ont lair sympas.\n$@c{serious_smile_fists}Bonne chance à toi !" "1": "@c{shock}Wah… Tu mas vraiment lavé.\nTes vraiment une débutante ?\n$@c{smile}Tas peut-être eu de la chance, mais…\nPeut-être que tarriveras jusquau bout du chemin.\n$Dailleurs, le prof ma demandé de te filer ces objets.\nIls ont lair sympas.\n$@c{serious_smile_fists}Bonne chance à toi !"
} }
}, },
"rival_female": { "rival_female": {
"encounter": { "encounter": {
"1": "@c{smile_wave}Ah, te voilà ! Je tai cherché partout !\n@c{angry_mopen}On oublie de dire au revoir à sa meilleure amie ?\n$@c{smile_ehalf}Tas décidé de réaliser ton rêve, hein ?\nCe jour est donc vraiment arrivé…\n$@c{smile}Je veux bien te pardonner de mavoir oubliée,\nà une conditon. @c{smile_wave_wink}Que tu maffronte !\n$@c{angry_mopen}Donne tout ! Ce serait dommage que ton aventure finisse avant davoir commencé, hein ?" "1": "@c{smile_wave}Ah, te voilà ! Je tai cherché partout !\n@c{angry_mopen}On oublie de dire au revoir à sa meilleure amie ?\n$@c{smile_ehalf}Tas décidé de réaliser ton rêve, hein ?\nCe jour est donc vraiment arrivé…\n$@c{smile}Je veux bien te pardonner de mavoir oubliée,\nà une condition. @c{smile_wave_wink}Que tu maffronte !\n$@c{angry_mopen}Donne tout ! Ce serait dommage que ton aventure finisse avant davoir commencé, hein ?"
}, },
"victory": { "victory": {
"1": "@c{shock}Tu viens de commencer et tes déjà si fort ?!@d{96}\n@c{angry}Tas triché non ? Avoue !\n$@c{smile_wave_wink}Jdéconne !@d{64} @c{smile_eclosed}Jai perdu dans les règles…\nJai le sentiment que tu vas très bien ten sortir.\n$@c{smile}Dailleurs, le prof veut que je te donne ces quelques objets. Ils te seront utiles, pour sûr !\n$@c{smile_wave}Fais de ton mieux, comme toujours !\nJe crois fort en toi !" "1": "@c{shock}Tu viens de commencer et tes déjà si fort ?!@d{96}\n@c{angry}Tas triché non ? Avoue !\n$@c{smile_wave_wink}Jdéconne !@d{64} @c{smile_eclosed}Jai perdu dans les règles…\nJai le sentiment que tu vas très bien ten sortir.\n$@c{smile}Dailleurs, le prof veut que je te donne ces quelques objets. Ils te seront utiles, pour sûr !\n$@c{smile_wave}Fais de ton mieux, comme toujours !\nJe crois fort en toi !"
@ -521,10 +611,10 @@
}, },
"rival_2": { "rival_2": {
"encounter": { "encounter": {
"1": "@c{smile}Hé, toi aussi tes là ?\n@c{smile_eclosed}Toujours invaincu, hein… ?\n$@c{serious_mopen_fists}Je sais que jai lair de tavoir suivi ici, mais cest pas complètement vrai.\n$@c{serious_smile_fists}Pour être honnête, ça me démangeait davoir une revanche depuis que tu mas battu.\n$Je me suis beaucoup entrainé, alors sois sure que je vais pas retenir mes coups cette fois.\n$@c{serious_mopen_fists}Et comme la dernière fois, ne te retiens pas !\nCest parti !" "1": "@c{smile}Hé, toi aussi tes là ?\n@c{smile_eclosed}Toujours invaincue, hein… ?\n$@c{serious_mopen_fists}Je sais que jai lair de tavoir suivie ici, mais cest pas complètement vrai.\n$@c{serious_smile_fists}Pour être honnête, ça me démangeait davoir une revanche depuis que tu mas battu.\n$Je me suis beaucoup entrainé, alors sois sure que je vais pas retenir mes coups cette fois.\n$@c{serious_mopen_fists}Et comme la dernière fois, ne te retiens pas !\nCest parti !"
}, },
"victory": { "victory": {
"1": "@c{neutral_eclosed}Oh. Je crois que jai trop pris la confiance.\n$@c{smile}Pas grave, cest OK. Je me doutais que ça arriverait.\n@c{serious_mopen_fists}Je vais juste devoir encore plus mentrainer !\n\n$@c{smile}Ah, et pas que taies réellement besoin daide, mais jai ça en trop sur moi qui pourrait tintéresser.\n\n$@c{serious_smile_fists}Mais nespère plus en avoir dautres !\nJe peux pas passer mon temps à aider mon adversaire.\n$@c{smile}Bref, prends soin de toi et profite bien de lévènement !" "1": "@c{neutral_eclosed}Oh. Je crois que jai trop pris la confiance.\n$@c{smile}Pas grave, cest OK. Je me doutais que ça arriverait.\n@c{serious_mopen_fists}Je vais juste devoir encore plus mentrainer !\n\n$@c{smile}Ah, et pas que taies réellement besoin daide, mais jai ça en trop sur moi qui pourrait tintéresser.\n\n$@c{serious_smile_fists}Mais nespère plus en avoir dautres !\nJe peux pas passer mon temps à aider mon adversaire.\n$@c{smile}Bref, prends soin de toi !"
} }
}, },
"rival_2_female": { "rival_2_female": {
@ -532,7 +622,7 @@
"1": "@c{smile_wave}Hé, sympa de te croiser ici. Tas toujours lair invaincu. @c{angry_mopen}Eh… Pas mal !\n$@c{angry_mopen}Je sais à quoi tu penses et non, je tespionne pas.\n@c{smile_eclosed}Cest juste que jétais aussi dans le coin.\n$@c{smile_ehalf}Heureuse pour toi, mais je veux juste te rappeler que cest pas grave de perdre parfois.\n$@c{smile}On apprend de nos erreurs, souvent plus que si on ne connaissait que le succès.\n$@c{angry_mopen}Dans tous les cas je me suis bien entrainée pour cette revanche, tas intérêt à tout donner !" "1": "@c{smile_wave}Hé, sympa de te croiser ici. Tas toujours lair invaincu. @c{angry_mopen}Eh… Pas mal !\n$@c{angry_mopen}Je sais à quoi tu penses et non, je tespionne pas.\n@c{smile_eclosed}Cest juste que jétais aussi dans le coin.\n$@c{smile_ehalf}Heureuse pour toi, mais je veux juste te rappeler que cest pas grave de perdre parfois.\n$@c{smile}On apprend de nos erreurs, souvent plus que si on ne connaissait que le succès.\n$@c{angry_mopen}Dans tous les cas je me suis bien entrainée pour cette revanche, tas intérêt à tout donner !"
}, },
"victory": { "victory": {
"1": "@c{neutral}Je… Jétais pas encore supposée perdre…\n$@c{smile}Bon. Ça veut juste dire que je vais devoir encore plus mentrainer !\n$@c{smile_wave}Jai aussi ça en rab pour toi !\n@c{smile_wave_wink}Inutile de me remercier ~.\n$@c{angry_mopen}Cétaient les derniers, terminé les cadeaux après ceux-là !\n$@c{smile_wave}Allez, tiens le coup et profite bien de lévènement !" "1": "@c{neutral}Je… Jétais pas encore supposée perdre…\n$@c{smile}Bon. Ça veut juste dire que je vais devoir encore plus mentrainer !\n$@c{smile_wave}Jai aussi ça en rab pour toi !\n@c{smile_wave_wink}Inutile de me remercier ~.\n$@c{angry_mopen}Cétaient les derniers, terminé les cadeaux après ceux-là !\n$@c{smile_wave}Allez, tiens le coup !"
}, },
"defeat": { "defeat": {
"1": "Je suppose que cest parfois normal de perdre…" "1": "Je suppose que cest parfois normal de perdre…"
@ -540,7 +630,7 @@
}, },
"rival_3": { "rival_3": {
"encounter": { "encounter": {
"1": "@c{smile}Hé, mais qui voilà ! Ça fait un bail.\n@c{neutral}Tes… toujours invaincu ? Incroyable.\n$@c{neutral_eclosed}Tout est devenu un peu… étrange.\nCest plus pareil sans toi au village.\n$@c{serious}Je sais que cest égoïste, mais jai besoin dexpier ça.\n@c{neutral_eclosed}Je crois que tout ça te dépasse.\n$@c{serious}Ne jamais perdre, cest juste irréaliste.\nGrandir, cest parfois aussi savoir perdre.\n$@c{neutral_eclosed}Tas un beau parcours, mais il y a encore tellement à venir et ça va pas sarranger. @c{neutral}Tes prêt pour ça ?\n$@c{serious_mopen_fists}Si tu les, alors prouve-le." "1": "@c{smile}Hé, mais qui voilà ! Ça fait un bail.\n@c{neutral}Tes… toujours invaincue ? Incroyable.\n$@c{neutral_eclosed}Tout est devenu un peu… étrange.\nCest plus pareil sans toi au village.\n$@c{serious}Je sais que cest égoïste, mais jai besoin dexpier ça.\n@c{neutral_eclosed}Je crois que tout ça te dépasse.\n$@c{serious}Ne jamais perdre, cest juste irréaliste.\nGrandir, cest parfois aussi savoir perdre.\n$@c{neutral_eclosed}Tas un beau parcours, mais il y a encore tellement à venir et ça va pas sarranger. @c{neutral}Tes prête pour ça ?\n$@c{serious_mopen_fists}Si tu les, alors prouve-le."
}, },
"victory": { "victory": {
"1": "@c{angry_mhalf}Cest lunaire… Jai presque fait que mentrainer…\nAlors pourquoi il y a encore un tel écart entre nous ?" "1": "@c{angry_mhalf}Cest lunaire… Jai presque fait que mentrainer…\nAlors pourquoi il y a encore un tel écart entre nous ?"
@ -559,7 +649,7 @@
}, },
"rival_4": { "rival_4": {
"encounter": { "encounter": {
"1": "@c{neutral}Hé.\n$Je vais pas y aller par quatre chemins avec toi.\n@c{neutral_eclosed}Je suis là pour gagner. Simple, basique.\n$@c{serious_mhalf_fists}Jai appris à maximiser tout mon potentiel en mentrainant darrachepied.\n$@c{smile}Cest fou tout le temps que tu peux te dégager si tu dors pas en sacrifiant ta vie sociale.\n$@c{serious_mopen_fists}Plus rien na dimportance désormais, pas tant que jaurai pas gagné.\n$@c{neutral_eclosed}Jai atteint un stade où je ne peux plus perdre.\n@c{smile_eclosed}Je présume que ta philosophie était pas si fausse finalement.\n$@c{angry_mhalf}La défaite, cest pour les faibles, et je ne suis plus un faible.\n$@c{serious_mopen_fists}Tiens-toi prêt." "1": "@c{neutral}Hé.\n$Je vais pas y aller par quatre chemins avec toi.\n@c{neutral_eclosed}Je suis là pour gagner. Simple, basique.\n$@c{serious_mhalf_fists}Jai appris à maximiser tout mon potentiel en mentrainant darrachepied.\n$@c{smile}Cest fou tout le temps que tu peux te dégager si tu dors pas en sacrifiant ta vie sociale.\n$@c{serious_mopen_fists}Plus rien na dimportance désormais, pas tant que jaurai pas gagné.\n$@c{neutral_eclosed}Jai atteint un stade où je ne peux plus perdre.\n@c{smile_eclosed}Je présume que ta philosophie était pas si fausse finalement.\n$@c{angry_mhalf}La défaite, cest pour les faibles, et je ne suis plus un faible.\n$@c{serious_mopen_fists}Tiens-toi prête."
}, },
"victory": { "victory": {
"1": "@c{neutral}Que…@d{64} Qui es-tu ?" "1": "@c{neutral}Que…@d{64} Qui es-tu ?"
@ -597,7 +687,7 @@
}, },
"rival_6": { "rival_6": {
"encounter": { "encounter": {
"1": "@c{smile_eclosed}Nous y revoilà.\n$@c{neutral}Jai eu du temps pour réfléchir à tout ça.\nIl y a une raison à pourquoi tout semble étrange.\n$@c{neutral_eclosed}Ton rêve, ma volonté de te battre…\nFont partie de quelque chose de plus grand.\n$@c{serious}Cest même pas à propos de moi, ni de toi… Mais du monde, @c{serious_mhalf_fists}et te repousser dans tes limites est ma mission.\n$@c{neutral_eclosed}Jignore si je serai capable de laccomplir, mais je ferai tout ce qui est en mon pouvoir.\n$@c{neutral}Cet endroit est terrifiant… Et pourtant il ma lair familier, comme si jy avais déjà mis les pieds.\n$@c{serious_mhalf_fists}Tu ressens la même chose, pas vrai ?\n$@c{serious}… et cest comme si quelque chose ici me parlait.\n$Comme si cétait tout ce que ce monde avait toujours connu.\n$Ces précieux moments ensemble semblent si proches ne sont rien de plus quun lointain souvenir.\n$@c{neutral_eclosed}Dailleurs, qui peut dire aujourdhui quils ont pu être réels ?\n$@c{serious_mopen_fists}Il faut que tu persévères. Si tu tarrêtes, ça naura jamais de fin et tes le seul à en être capable.\n$@c{serious_smile_fists}Difficile de comprendre le sens de tout ça, je sais juste que cest la réalité.\n$@c{serious_mopen_fists}Si tu ne parviens pas à me battre ici et maintenant, tu nas aucune chance." "1": "@c{smile_eclosed}Nous y revoilà.\n$@c{neutral}Jai eu du temps pour réfléchir à tout ça.\nIl y a une raison à pourquoi tout semble étrange.\n$@c{neutral_eclosed}Ton rêve, ma volonté de te battre…\nFont partie de quelque chose de plus grand.\n$@c{serious}Cest même pas à propos de moi, ni de toi… Mais du monde, @c{serious_mhalf_fists}et te repousser dans tes limites est ma mission.\n$@c{neutral_eclosed}Jignore si je serai capable de laccomplir, mais je ferai tout ce qui est en mon pouvoir.\n$@c{neutral}Cet endroit est terrifiant… Et pourtant il ma lair familier, comme si jy avais déjà mis les pieds.\n$@c{serious_mhalf_fists}Tu ressens la même chose, pas vrai ?\n$@c{serious}… et cest comme si quelque chose ici me parlait.\n$Comme si cétait tout ce que ce monde avait toujours connu.\n$Ces précieux moments ensemble semblent si proches ne sont rien de plus quun lointain souvenir.\n$@c{neutral_eclosed}Dailleurs, qui peut dire aujourdhui quils ont pu être réels ?\n$@c{serious_mopen_fists}Il faut que tu persévères. Si tu tarrêtes, ça naura jamais de fin et tes la seule à en être capable.\n$@c{serious_smile_fists}Difficile de comprendre le sens de tout ça, je sais juste que cest la réalité.\n$@c{serious_mopen_fists}Si tu ne parviens pas à me battre ici et maintenant, tu nas aucune chance."
}, },
"victory": { "victory": {
"1": "@c{smile_eclosed}Jai fait ce que javais à faire.\n$Promets-moi juste une chose.\n@c{smile}Après avoir réparé ce monde… Rentre à la maison." "1": "@c{smile_eclosed}Jai fait ce que javais à faire.\n$Promets-moi juste une chose.\n@c{smile}Après avoir réparé ce monde… Rentre à la maison."

View File

@ -25,5 +25,6 @@
"unlinkGoogle": "Délier Google", "unlinkGoogle": "Délier Google",
"cancel": "Retour", "cancel": "Retour",
"losingProgressionWarning": "Vous allez perdre votre progression depuis le début du combat. Continuer ?", "losingProgressionWarning": "Vous allez perdre votre progression depuis le début du combat. Continuer ?",
"noEggs": "Vous ne faites actuellement\néclore aucun Œuf !" "noEggs": "Vous ne faites actuellement\néclore aucun Œuf !",
} "donate": "Faire un don"
}

View File

@ -49,8 +49,8 @@
"DoubleBattleChanceBoosterModifierType": { "DoubleBattleChanceBoosterModifierType": {
"description": "Double les chances de tomber sur un combat double pendant {{battleCount}} combats." "description": "Double les chances de tomber sur un combat double pendant {{battleCount}} combats."
}, },
"TempBattleStatBoosterModifierType": { "TempStatStageBoosterModifierType": {
"description": "Augmente dun cran {{tempBattleStatName}} pour toute léquipe pendant 5 combats." "description": "Augmente dun cran {{stat}} pour toute léquipe pendant 5 combats."
}, },
"AttackTypeBoosterModifierType": { "AttackTypeBoosterModifierType": {
"description": "Augmente de 20% la puissance des capacités de type {{moveType}} dun Pokémon." "description": "Augmente de 20% la puissance des capacités de type {{moveType}} dun Pokémon."
@ -61,8 +61,8 @@
"AllPokemonLevelIncrementModifierType": { "AllPokemonLevelIncrementModifierType": {
"description": "Fait monter toute léquipe de {{levels}} niveau·x." "description": "Fait monter toute léquipe de {{levels}} niveau·x."
}, },
"PokemonBaseStatBoosterModifierType": { "BaseStatBoosterModifierType": {
"description": "Augmente de 10% {{statName}} de base de son porteur. Plus les IV sont hauts, plus il peut en porter." "description": "Augmente de 10% {{stat}} de base de son porteur. Plus les IV sont hauts, plus il peut en porter."
}, },
"AllPokemonFullHpRestoreModifierType": { "AllPokemonFullHpRestoreModifierType": {
"description": "Restaure tous les PV de toute léquipe." "description": "Restaure tous les PV de toute léquipe."
@ -183,6 +183,7 @@
"SOOTHE_BELL": { "name": "Grelot Zen" }, "SOOTHE_BELL": { "name": "Grelot Zen" },
"SCOPE_LENS": { "name": "Lentilscope", "description": "Une lentille qui augmente dun cran le taux de critiques du porteur." }, "SCOPE_LENS": { "name": "Lentilscope", "description": "Une lentille qui augmente dun cran le taux de critiques du porteur." },
"DIRE_HIT": { "name": "Muscle +", "extra": { "raises": "Taux de critique" } },
"LEEK": { "name": "Poireau", "description": "À faire tenir à Canarticho ou Palarticho. Un poireau très long et solide qui augmente de 2 crans le taux de critiques." }, "LEEK": { "name": "Poireau", "description": "À faire tenir à Canarticho ou Palarticho. Un poireau très long et solide qui augmente de 2 crans le taux de critiques." },
"EVIOLITE": { "name": "Évoluroc", "description": "Augmente de 50% la Défense et Déf. Spé. si le porteur peut évoluer, 25% aux fusions dont une moitié le peut encore." }, "EVIOLITE": { "name": "Évoluroc", "description": "Augmente de 50% la Défense et Déf. Spé. si le porteur peut évoluer, 25% aux fusions dont une moitié le peut encore." },
@ -250,28 +251,14 @@
"METAL_POWDER": { "name": "Poudre Métal", "description": "À faire tenir à Métamorph. Cette poudre étrange, très fine mais résistante, double sa Défense." }, "METAL_POWDER": { "name": "Poudre Métal", "description": "À faire tenir à Métamorph. Cette poudre étrange, très fine mais résistante, double sa Défense." },
"QUICK_POWDER": { "name": "Poudre Vite", "description": "À faire tenir à Métamorph. Cette poudre étrange, très fine mais résistante, double sa Vitesse." } "QUICK_POWDER": { "name": "Poudre Vite", "description": "À faire tenir à Métamorph. Cette poudre étrange, très fine mais résistante, double sa Vitesse." }
}, },
"TempBattleStatBoosterItem": { "TempStatStageBoosterItem": {
"x_attack": "Attaque +", "x_attack": "Attaque +",
"x_defense": "Défense +", "x_defense": "Défense +",
"x_sp_atk": "Atq. Spé. +", "x_sp_atk": "Atq. Spé. +",
"x_sp_def": "Déf. Spé. +", "x_sp_def": "Déf. Spé. +",
"x_speed": "Vitesse +", "x_speed": "Vitesse +",
"x_accuracy": "Précision +", "x_accuracy": "Précision +"
"dire_hit": "Muscle +"
}, },
"TempBattleStatBoosterStatName": {
"ATK": "lAttaque",
"DEF": "la Défense",
"SPATK": "lAtq. Spé.",
"SPDEF": "la Déf. Spé.",
"SPD": "la Vitesse",
"ACC": "la précision",
"CRIT": "le taux de critique",
"EVA": "lesquive",
"DEFAULT": "???"
},
"AttackTypeBoosterItem": { "AttackTypeBoosterItem": {
"silk_scarf": "Mouchoir Soie", "silk_scarf": "Mouchoir Soie",
"black_belt": "Ceinture Noire", "black_belt": "Ceinture Noire",

View File

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

View File

@ -3,6 +3,10 @@
"cutHpPowerUpMove": "{{pokemonName}} sacrifie des PV\net augmente la puissance ses capacités !", "cutHpPowerUpMove": "{{pokemonName}} sacrifie des PV\net augmente la puissance ses capacités !",
"absorbedElectricity": "{{pokemonName}} absorbe de lélectricité !", "absorbedElectricity": "{{pokemonName}} absorbe de lélectricité !",
"switchedStatChanges": "{{pokemonName}} permute\nles changements de stats avec ceux de sa cible !", "switchedStatChanges": "{{pokemonName}} permute\nles changements de stats avec ceux de sa cible !",
"switchedTwoStatChanges": "{{pokemonName}} permute les changements de {{firstStat} et de {{secondStat}} avec ceux de sa cible !",
"switchedStat": "{{pokemonName}} et sa cible échangent leur {{stat}} !",
"sharedGuard": "{{pokemonName}} additionne sa garde à celle de sa cible et redistribue le tout équitablement !",
"sharedPower": "{{pokemonName}} additionne sa force à celle de sa cible et redistribue le tout équitablement !",
"goingAllOutForAttack": "{{pokemonName}} a pris\ncette capacité au sérieux !", "goingAllOutForAttack": "{{pokemonName}} a pris\ncette capacité au sérieux !",
"regainedHealth": "{{pokemonName}}\nrécupère des PV !", "regainedHealth": "{{pokemonName}}\nrécupère des PV !",
"keptGoingAndCrashed": "{{pokemonName}}\nsécrase au sol !", "keptGoingAndCrashed": "{{pokemonName}}\nsécrase au sol !",

View File

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

View File

@ -80,7 +80,7 @@
"100_RIBBONS": { "100_RIBBONS": {
"name": "Campione Lega Assoluta" "name": "Campione Lega Assoluta"
}, },
"TRANSFER_MAX_BATTLE_STAT": { "TRANSFER_MAX_STAT_STAGE": {
"name": "Lavoro di Squadra", "name": "Lavoro di Squadra",
"description": "Trasferisci almeno sei bonus statistiche tramite staffetta" "description": "Trasferisci almeno sei bonus statistiche tramite staffetta"
}, },
@ -261,4 +261,4 @@
"name": "Buona la prima!", "name": "Buona la prima!",
"description": "Completa la modalità sfida 'Un nuovo inizio'." "description": "Completa la modalità sfida 'Un nuovo inizio'."
} }
} }

View File

@ -49,8 +49,8 @@
"DoubleBattleChanceBoosterModifierType": { "DoubleBattleChanceBoosterModifierType": {
"description": "Raddoppia la possibilità di imbattersi in doppie battaglie per {{battleCount}} battaglie." "description": "Raddoppia la possibilità di imbattersi in doppie battaglie per {{battleCount}} battaglie."
}, },
"TempBattleStatBoosterModifierType": { "TempStatStageBoosterModifierType": {
"description": "Aumenta {{tempBattleStatName}} di un livello a tutti i Pokémon nel gruppo per 5 battaglie." "description": "Aumenta la statistica {{stat}} di un livello\na tutti i Pokémon nel gruppo per 5 battaglie."
}, },
"AttackTypeBoosterModifierType": { "AttackTypeBoosterModifierType": {
"description": "Aumenta la potenza delle mosse di tipo {{moveType}} del 20% per un Pokémon." "description": "Aumenta la potenza delle mosse di tipo {{moveType}} del 20% per un Pokémon."
@ -59,10 +59,10 @@
"description": "Aumenta il livello di un Pokémon di {{levels}}." "description": "Aumenta il livello di un Pokémon di {{levels}}."
}, },
"AllPokemonLevelIncrementModifierType": { "AllPokemonLevelIncrementModifierType": {
"description": "Aumenta i livell di tutti i Pokémon della squadra di {{levels}}." "description": "Aumenta il livello di tutti i Pokémon della squadra di {{levels}}."
}, },
"PokemonBaseStatBoosterModifierType": { "BaseStatBoosterModifierType": {
"description": "Aumenta {{statName}} di base del possessore del 10%." "description": "Aumenta l'/la {{stat}} di base del possessore del 10%."
}, },
"AllPokemonFullHpRestoreModifierType": { "AllPokemonFullHpRestoreModifierType": {
"description": "Restituisce il 100% dei PS a tutti i Pokémon." "description": "Restituisce il 100% dei PS a tutti i Pokémon."
@ -248,6 +248,12 @@
"name": "Mirino", "name": "Mirino",
"description": "Lente che aumenta la probabilità di sferrare brutti colpi." "description": "Lente che aumenta la probabilità di sferrare brutti colpi."
}, },
"DIRE_HIT": {
"name": "Supercolpo",
"extra": {
"raises": "Tasso di brutti colpi"
}
},
"LEEK": { "LEEK": {
"name": "Porro", "name": "Porro",
"description": "Strumento da dare a Farfetch'd. Lungo gambo di porro che aumenta la probabilità di sferrare brutti colpi." "description": "Strumento da dare a Farfetch'd. Lungo gambo di porro che aumenta la probabilità di sferrare brutti colpi."
@ -411,25 +417,13 @@
"description": "Strumento da dare a Ditto. Questa strana polvere, fine e al contempo dura, aumenta la Velocità." "description": "Strumento da dare a Ditto. Questa strana polvere, fine e al contempo dura, aumenta la Velocità."
} }
}, },
"TempBattleStatBoosterItem": { "TempStatStageBoosterItem": {
"x_attack": "Attacco X", "x_attack": "Attacco X",
"x_defense": "Difesa X", "x_defense": "Difesa X",
"x_sp_atk": "Att. Speciale X", "x_sp_atk": "Att. Speciale X",
"x_sp_def": "Dif. Speciale X", "x_sp_def": "Dif. Speciale X",
"x_speed": "Velocità X", "x_speed": "Velocità X",
"x_accuracy": "Precisione X", "x_accuracy": "Precisione X"
"dire_hit": "Supercolpo"
},
"TempBattleStatBoosterStatName": {
"ATK": "Attacco",
"DEF": "Difesa",
"SPATK": "Att. Speciale",
"SPDEF": "Dif. Speciale",
"SPD": "Velocità",
"ACC": "Precisione",
"CRIT": "Tasso di brutti colpi",
"EVA": "Elusione",
"DEFAULT": "???"
}, },
"AttackTypeBoosterItem": { "AttackTypeBoosterItem": {
"silk_scarf": "Sciarpa seta", "silk_scarf": "Sciarpa seta",
@ -606,4 +600,4 @@
"FAIRY_MEMORY": "ROM Folletto", "FAIRY_MEMORY": "ROM Folletto",
"NORMAL_MEMORY": "ROM Normale" "NORMAL_MEMORY": "ROM Normale"
} }
} }

View File

@ -3,7 +3,7 @@
"turnHealApply": "{{pokemonNameWithAffix}} recupera alcuni PS con\nil/la suo/a {{typeName}}!", "turnHealApply": "{{pokemonNameWithAffix}} recupera alcuni PS con\nil/la suo/a {{typeName}}!",
"hitHealApply": "{{pokemonNameWithAffix}} recupera alcuni PS con\nil/la suo/a {{typeName}}!", "hitHealApply": "{{pokemonNameWithAffix}} recupera alcuni PS con\nil/la suo/a {{typeName}}!",
"pokemonInstantReviveApply": "{{pokemonNameWithAffix}} torna in forze\ngrazie al/alla suo/a {{typeName}}!", "pokemonInstantReviveApply": "{{pokemonNameWithAffix}} torna in forze\ngrazie al/alla suo/a {{typeName}}!",
"pokemonResetNegativeStatStageApply": "La riduzione alle statistiche di {{pokemonNameWithAffix}}\nviene annullata grazie al/alla suo/a {{typeName}}!", "resetNegativeStatStageApply": "La riduzione alle statistiche di {{pokemonNameWithAffix}}\nviene annullata grazie al/alla suo/a {{typeName}}!",
"moneyInterestApply": "Ricevi un interesse pari a {{moneyAmount}}₽\ngrazie al/allo/a {{typeName}}!", "moneyInterestApply": "Ricevi un interesse pari a {{moneyAmount}}₽\ngrazie al/allo/a {{typeName}}!",
"turnHeldItemTransferApply": "Il/l'/lo/la {{itemName}} di {{pokemonNameWithAffix}} è stato assorbito\ndal {{typeName}} di {{pokemonName}}!", "turnHeldItemTransferApply": "Il/l'/lo/la {{itemName}} di {{pokemonNameWithAffix}} è stato assorbito\ndal {{typeName}} di {{pokemonName}}!",
"contactHeldItemTransferApply": "Il/l'/lo/la {{itemName}} di {{pokemonNameWithAffix}} è stato rubato\nda {{pokemonName}} con {{typeName}}!", "contactHeldItemTransferApply": "Il/l'/lo/la {{itemName}} di {{pokemonNameWithAffix}} è stato rubato\nda {{pokemonName}} con {{typeName}}!",

View File

@ -3,6 +3,10 @@
"cutHpPowerUpMove": "{{pokemonName}} riduce i suoi PS per potenziare la sua mossa!", "cutHpPowerUpMove": "{{pokemonName}} riduce i suoi PS per potenziare la sua mossa!",
"absorbedElectricity": "{{pokemonName}} assorbe elettricità!", "absorbedElectricity": "{{pokemonName}} assorbe elettricità!",
"switchedStatChanges": "{{pokemonName}} scambia con il bersaglio le modifiche alle statistiche!", "switchedStatChanges": "{{pokemonName}} scambia con il bersaglio le modifiche alle statistiche!",
"switchedTwoStatChanges": "{{pokemonName}} scambia con il bersaglio le modifiche a {{firstStat}} e {{secondStat}}!",
"switchedStat": "{{pokemonName}} scambia la sua {{stat}} con quella del bersaglio!",
"sharedGuard": "{{pokemonName}} somma le sue capacità difensive con quelle del bersaglio e le ripartisce equamente!",
"sharedPower": "{{pokemonName}} somma le sue capacità offensive con quelle del bersaglio e le ripartisce equamente!",
"goingAllOutForAttack": "{{pokemonName}} fa sul serio!", "goingAllOutForAttack": "{{pokemonName}} fa sul serio!",
"regainedHealth": "{{pokemonName}} s'è\nripreso!", "regainedHealth": "{{pokemonName}} s'è\nripreso!",
"keptGoingAndCrashed": "{{pokemonName}} si sbilancia e\nsi schianta!", "keptGoingAndCrashed": "{{pokemonName}} si sbilancia e\nsi schianta!",

View File

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

View File

@ -81,7 +81,7 @@
"100_RIBBONS": { "100_RIBBONS": {
"name": "マスターリーグチャンピオン" "name": "マスターリーグチャンピオン"
}, },
"TRANSFER_MAX_BATTLE_STAT": { "TRANSFER_MAX_STAT_STAGE": {
"name": "同力", "name": "同力",
"description": "少なくとも 一つの 能力を 最大まで あげて\n他の 手持ちポケモンに バトンタッチする" "description": "少なくとも 一つの 能力を 最大まで あげて\n他の 手持ちポケモンに バトンタッチする"
}, },

View File

@ -49,8 +49,8 @@
"DoubleBattleChanceBoosterModifierType": { "DoubleBattleChanceBoosterModifierType": {
"description": "バトル{{battleCount}}かいのあいだ ダブルバトルになるかくりつを2ばいにする" "description": "バトル{{battleCount}}かいのあいだ ダブルバトルになるかくりつを2ばいにする"
}, },
"TempBattleStatBoosterModifierType": { "TempStatStageBoosterModifierType": {
"description": "すべてのパーティメンバーの {{tempBattleStatName}}を5かいのバトルのあいだ 1だんかいあげる" "description": "すべてのパーティメンバーの {{stat}}を5かいのバトルのあいだ 1だんかいあげる"
}, },
"AttackTypeBoosterModifierType": { "AttackTypeBoosterModifierType": {
"description": "ポケモンの {{moveType}}タイプのわざのいりょくを20パーセントあげる" "description": "ポケモンの {{moveType}}タイプのわざのいりょくを20パーセントあげる"
@ -61,8 +61,8 @@
"AllPokemonLevelIncrementModifierType": { "AllPokemonLevelIncrementModifierType": {
"description": "すべてのパーティメンバーのレベルを1あげる" "description": "すべてのパーティメンバーのレベルを1あげる"
}, },
"PokemonBaseStatBoosterModifierType": { "BaseStatBoosterModifierType": {
"description": "ポケモンの{{statName}}のきほんステータスを10パーセントあげる。こたいちがたかいほどスタックのげんかいもたかくなる。" "description": "ポケモンの{{stat}}のきほんステータスを10パーセントあげる。こたいちがたかいほどスタックのげんかいもたかくなる。"
}, },
"AllPokemonFullHpRestoreModifierType": { "AllPokemonFullHpRestoreModifierType": {
"description": "すべてのポケモンのHPを100パーセントかいふくする" "description": "すべてのポケモンのHPを100パーセントかいふくする"
@ -248,6 +248,12 @@
"name": "ピントレンズ", "name": "ピントレンズ",
"description": "弱点が 見える レンズ。持たせた ポケモンの技が 急所に 当たりやすくなる。" "description": "弱点が 見える レンズ。持たせた ポケモンの技が 急所に 当たりやすくなる。"
}, },
"DIRE_HIT": {
"name": "クリティカット",
"extra": {
"raises": "きゅうしょりつ"
}
},
"LEEK": { "LEEK": {
"name": "ながねぎ", "name": "ながねぎ",
"description": "とても長くて 硬いクキ。カモネギに 持たせると 技が 急所に 当たりやすくなる。" "description": "とても長くて 硬いクキ。カモネギに 持たせると 技が 急所に 当たりやすくなる。"
@ -411,25 +417,13 @@
"description": "メタモンに 持たせると 素早さが あがる 不思議 粉。とても こまかくて 硬い。" "description": "メタモンに 持たせると 素早さが あがる 不思議 粉。とても こまかくて 硬い。"
} }
}, },
"TempBattleStatBoosterItem": { "TempStatStageBoosterItem": {
"x_attack": "プラスパワー", "x_attack": "プラスパワー",
"x_defense": "ディフェンダー", "x_defense": "ディフェンダー",
"x_sp_atk": "スペシャルアップ", "x_sp_atk": "スペシャルアップ",
"x_sp_def": "スペシャルガード", "x_sp_def": "スペシャルガード",
"x_speed": "スピーダー", "x_speed": "スピーダー",
"x_accuracy": "ヨクアタール", "x_accuracy": "ヨクアタール"
"dire_hit": "クリティカット"
},
"TempBattleStatBoosterStatName": {
"ATK": "こうげき",
"DEF": "ぼうぎょ",
"SPATK": "とくこう",
"SPDEF": "とくぼう",
"SPD": "すばやさ",
"ACC": "めいちゅう",
"CRIT": "きゅうしょりつ",
"EVA": "かいひ",
"DEFAULT": "???"
}, },
"AttackTypeBoosterItem": { "AttackTypeBoosterItem": {
"silk_scarf": "シルクのスカーフ", "silk_scarf": "シルクのスカーフ",
@ -569,4 +563,4 @@
"DOUSE_DRIVE": "アクアカセット", "DOUSE_DRIVE": "アクアカセット",
"ULTRANECROZIUM_Z": "ウルトラネクロZ" "ULTRANECROZIUM_Z": "ウルトラネクロZ"
} }
} }

View File

@ -3,7 +3,7 @@
"turnHealApply": "{{pokemonNameWithAffix}}は\n{{typeName}}で 少し 回復!", "turnHealApply": "{{pokemonNameWithAffix}}は\n{{typeName}}で 少し 回復!",
"hitHealApply": "{{pokemonNameWithAffix}}は\n{{typeName}}で 少し 回復!", "hitHealApply": "{{pokemonNameWithAffix}}は\n{{typeName}}で 少し 回復!",
"pokemonInstantReviveApply": "{{pokemonNameWithAffix}}は\n{{typeName}}で 復活した!", "pokemonInstantReviveApply": "{{pokemonNameWithAffix}}は\n{{typeName}}で 復活した!",
"pokemonResetNegativeStatStageApply": "{{pokemonNameWithAffix}}は {{typeName}}で\n下がった能力が 元に戻った", "resetNegativeStatStageApply": "{{pokemonNameWithAffix}}は {{typeName}}で\n下がった能力が 元に戻った",
"moneyInterestApply": "{{typeName}}から {{moneyAmount}}円 取得した!", "moneyInterestApply": "{{typeName}}から {{moneyAmount}}円 取得した!",
"turnHeldItemTransferApply": "{{pokemonName}}の {{typeName}}が\n{{pokemonNameWithAffix}}の {{itemName}}を 吸い取った!", "turnHeldItemTransferApply": "{{pokemonName}}の {{typeName}}が\n{{pokemonNameWithAffix}}の {{itemName}}を 吸い取った!",
"contactHeldItemTransferApply": "{{pokemonName}}の {{typeName}}が\n{{pokemonNameWithAffix}}の {{itemName}}を うばい取った!", "contactHeldItemTransferApply": "{{pokemonName}}の {{typeName}}が\n{{pokemonNameWithAffix}}の {{itemName}}を うばい取った!",

View File

@ -2,7 +2,9 @@
"hitWithRecoil": "{{pokemonName}}は\nはんどうによる ダメージを うけた", "hitWithRecoil": "{{pokemonName}}は\nはんどうによる ダメージを うけた",
"cutHpPowerUpMove": "{{pokemonName}}は\nたいりょくを けずって パワーぜんかい", "cutHpPowerUpMove": "{{pokemonName}}は\nたいりょくを けずって パワーぜんかい",
"absorbedElectricity": "{{pokemonName}}は\n でんきを きゅうしゅうした", "absorbedElectricity": "{{pokemonName}}は\n でんきを きゅうしゅうした",
"switchedStatChanges": "{{pokemonName}}は あいてと じぶんのn\nのうりょくへんかを いれかえた", "switchedStatChanges": "{{pokemonName}}は あいてと じぶんの\nのうりょくへんかを いれかえた",
"sharedGuard": "{{pokemonName}}は\nおたがいのガードを シェアした",
"sharedPower": "{{pokemonName}}は\nおたがいのパワーを シェアした",
"goingAllOutForAttack": "{{pokemonName}}は\nほんきを だした", "goingAllOutForAttack": "{{pokemonName}}は\nほんきを だした",
"regainedHealth": "{{pokemonName}}は\nたいりょくを かいふくした", "regainedHealth": "{{pokemonName}}は\nたいりょくを かいふくした",
"keptGoingAndCrashed": "いきおいあまって {{pokemonName}}は\nじめんに ぶつかった", "keptGoingAndCrashed": "いきおいあまって {{pokemonName}}は\nじめんに ぶつかった",
@ -59,4 +61,4 @@
"suppressAbilities": "{{pokemonName}}の とくせいが きかなくなった!", "suppressAbilities": "{{pokemonName}}の とくせいが きかなくなった!",
"revivalBlessing": "{{pokemonName}}は\n復活して 戦えるようになった", "revivalBlessing": "{{pokemonName}}は\n復活して 戦えるようになった",
"swapArenaTags": "{{pokemonName}}は\nおたがいの ばのこうかを いれかえた" "swapArenaTags": "{{pokemonName}}は\nおたがいの ばのこうかを いれかえた"
} }

View File

@ -100,7 +100,7 @@
"moveTouchControls": "タッチ移動操作", "moveTouchControls": "タッチ移動操作",
"shopOverlayOpacity": "ショップオーバレイ不透明度", "shopOverlayOpacity": "ショップオーバレイ不透明度",
"shopCursorTarget": "ショップカーソル初位置", "shopCursorTarget": "ショップカーソル初位置",
"items": "アイテム", "rewards": "ご褒美",
"reroll": "選択肢変更", "reroll": "選択肢変更",
"shop": "ショップ", "shop": "ショップ",
"checkTeam": "手持ちを確認" "checkTeam": "手持ちを確認"

View File

@ -1 +1,130 @@
{} {
"ace_trainer": "エリートトレーナー",
"ace_trainer_female": "エリートトレーナー",
"ace_duo": "エリートコンビ",
"artist": "芸術家",
"artist_female": "芸術家",
"backers": "ファンクラブ",
"backpacker": "バックパッカー",
"backpacker_female": "バックパッカー",
"backpackers": "バックパッカーズ",
"baker": "ベーカリー",
"battle_girl": "バトルガール",
"beauty": "大人のおねえさん",
"beginners": "初心者",
"biker": "暴走族",
"black_belt": "カラテ王",
"breeder": "ポケモンブリーダー",
"breeder_female": "ポケモンブリーダー",
"breeders": "ブリーダーコンビ",
"clerk": "ビジネスマン",
"clerk_female": "",
"colleagues": "ビジネスパートナー",
"crush_kin": "格闘兄妹",
"cyclist": "サイクリング",
"cyclist_female": "サイクリング",
"cyclists": "サイクリングチーム",
"dancer": "ダンサー",
"dancer_female": "ダンサー",
"depot_agent": "鉄道員",
"doctor": "ドクター",
"doctor_female": "ドクター",
"firebreather": "火吹きやろう",
"fisherman": "釣り人",
"fisherman_female": "釣り人",
"gentleman": "ジェントルマン",
"guitarist": "ギタリスト",
"guitarist_female": "ギタリスト",
"harlequin": "クラウン",
"hiker": "山男",
"hooligans": "バッドチーム",
"hoopster": "バスケ選手",
"infielder": "野球選手",
"janitor": "清掃員",
"lady": "お嬢さま",
"lass": "ミニスカート",
"linebacker": "フットボーラー",
"maid": "メイド",
"madame": "マダム",
"medical_team": "医療チーム",
"musician": "ミュージシャン",
"hex_maniac": "オカルトマニア",
"nurse": "ナース",
"nursery_aide": "保育士",
"officer": "お巡りさん",
"parasol_lady": "パラソルおねえさん",
"pilot": "パイロット",
"pokéfan": "大好きクラブ",
"pokéfan_female": "大好きクラブ",
"pokéfan_family": "大好き夫婦",
"preschooler": "園児",
"preschooler_female": "園児",
"preschoolers": "園児たち",
"psychic": "サイキッカー",
"psychic_female": "サイキッカー",
"psychics": "サイキッ家",
"pokémon_ranger": "ポケモンレンジャー",
"pokémon_ranger_female": "ポケモンレンジャー",
"pokémon_rangers": "レンジャーズ",
"ranger": "レンジャー",
"restaurant_staff": "レストランスタッフ",
"rich": "お金持ち",
"rich_female": "お金持ち",
"rich_boy": "お坊っちゃま",
"rich_couple": "お二人さま",
"rich_kid": "ブルジョワ男子",
"rich_kid_female": "ブルジョワ女子",
"rich_kids": "ブルジョワ子達",
"roughneck": "スキンヘッズ",
"sailor": "船乗り",
"scientist": "研究員",
"scientist_female": "研究員",
"scientists": "研究チーム",
"smasher": "テニスプレイヤー",
"snow_worker": "冷凍作業員",
"snow_worker_female": "冷凍作業員",
"striker": "サッカー選手",
"school_kid": "塾帰り",
"school_kid_female": "塾帰り",
"school_kids": "塾生たち",
"swimmer": "海パンやろう",
"swimmer_female": "ビキニのおねえさん",
"swimmers": "水着カップル",
"twins": "双子ちゃん",
"veteran": "ベテラントレーナー",
"veteran_female": "ベテラントレーナー",
"veteran_duo": "ベテランコンビ",
"waiter": "ウエーター",
"waitress": "ウエートレス",
"worker": "作業員",
"worker_female": "作業員",
"workers": "作業班",
"youngster": "短パン小僧",
"rocket_grunt": "ロケット団の下っ端",
"rocket_grunts": " ロケット団の下っ端",
"rocket_grunt_female": "ロケット団の下っ端",
"magma_grunt": "マグマ団の下っ端",
"magma_grunt_female": "マグマ団の下っ端",
"magma_grunts": "マグマ団の下っ端",
"aqua_grunt": "アクア団の下っ端",
"aqua_grunt_female": "アクア団の下っ端",
"aqua_grunts": "アクア団の下っ端",
"galactic_grunt": "ギンガ団の下っ端",
"galactic_grunt_female": "ギンガ団の下っ端",
"galactic_grunts": "ギンガ団の下っ端",
"plasma_grunt": "プラスマ団の下っ端",
"plasma_grunt_female": "プラズマ団の下っ端",
"plasma_grunts": "プラズマ団の下っ端",
"flare_grunt": "フレア団の下っ端",
"flare_grunt_female": "フレア団の下っ端",
"flare_grunts": "フレア団の下っ端",
"aether_grunt": "エーテル財団の職員",
"aether_grunt_female": "エーテル財団の職員",
"aether_grunts": "エーテル財団の職員",
"skull_grunt": "スカル団の下っ端",
"skull_grunt_female": "スカル団の下っ端",
"skull_grunts": "スカル団の下っ端",
"macro_grunt": "マクロコスモスのトレーナ",
"macro_grunt_female": "マクロコスモスのトレーナ",
"macro_grunts": "マクロコスモスのトレーナ"
}

View File

@ -1 +1,164 @@
{} {
"brock": "タケシ",
"misty": "カスミ",
"lt_surge": "マチス",
"erika": "エリカ",
"janine": "アンズ",
"sabrina": "ナツメ",
"blaine": "カツラ",
"giovanni": "サカキ",
"falkner": "ハヤト",
"bugsy": "ツクシ",
"whitney": "アカネ",
"morty": "マツバ",
"chuck": "シジマ",
"jasmine": "ミカン",
"pryce": "ヤナギ",
"clair": "イブキ",
"roxanne": "ツツジ",
"brawly": "トウキ",
"wattson": "テッセン",
"flannery": "アスナ",
"norman": "センリ",
"winona": "ナギ",
"tate": "フウ",
"liza": "ラン",
"juan": "アダン",
"roark": "ヒョウタ",
"gardenia": "ナタネ",
"maylene": "スモモ",
"crasher_wake": "マキシ",
"fantina": "メリッサ",
"byron": "トウガン",
"candice": "スズナ",
"volkner": "デンジ",
"cilan": "デント",
"chili": "ポッド",
"cress": "コーン",
"cheren": "チェレン",
"lenora": "アロエ",
"roxie": "ホミカ",
"burgh": "アーティ",
"elesa": "カミツレ",
"clay": "ヤーコン",
"skyla": "フウロ",
"brycen": "ハチク",
"drayden": "シャガ",
"marlon": "シズイ",
"viola": "ビオラ",
"grant": "ザクロ",
"korrina": "コルニ",
"ramos": "フクジ",
"clemont": "シトロン",
"valerie": "マーシュ",
"olympia": "ゴジカ",
"wulfric": "ウルップ",
"milo": "ヤロー",
"nessa": "ルリナ",
"kabu": "カブ",
"bea": "サイトウ",
"allister": "オニオン",
"opal": "ポプラ",
"bede": "ビート",
"gordie": "マクワ",
"melony": "メロン",
"piers": "ネズ",
"marnie": "マリィ",
"raihan": "キバナ",
"katy": "カエデ",
"brassius": "コルサ",
"iono": " ナンジャモ",
"kofu": "ハイダイ",
"larry": "アオキ",
"ryme": "ライム",
"tulip": "リップ",
"grusha": "グルーシャ",
"lorelei": "カンナ",
"bruno": "シバ",
"agatha": "キクコ",
"lance": "ワタル",
"will": "イツキ",
"koga": "キョウ",
"karen": "カリン",
"sidney": "カゲツ",
"phoebe": "フヨウ",
"glacia": "プリム",
"drake": "ゲンジ",
"aaron": "リョウ",
"bertha": "キクノ",
"flint": "オーバ",
"lucian": "ゴヨウ",
"shauntal": "シキミ",
"marshal": "レンブ",
"grimsley": "ギーマ",
"caitlin": "カトレア",
"malva": "パキラ",
"siebold": "ズミ",
"wikstrom": "ガンピ",
"drasna": "ドラセナ",
"hala": "ハラ",
"molayne": "マーレイン",
"olivia": "ライチ",
"acerola": "アセロラ",
"kahili": "カヒリ",
"rika": "チリ",
"poppy": "ポピー",
"hassel": "ハッサク",
"crispin": "アカマツ",
"amarys": "ネリネ",
"lacey": "タロ",
"drayton": "カキツバタ",
"blue": "グリーン",
"red": "レッド",
"steven": "ダイゴ",
"wallace": "ミクリ",
"cynthia": "シロナ",
"alder": "アデク",
"iris": "アイリス",
"diantha": "カルネ",
"hau": "ハウ",
"geeta": "オモダカ",
"nemona": "ネモ",
"kieran": "スグリ",
"leon": "ダンデ",
"rival": "フィン",
"rival_female": "アイヴィー",
"archer": "アポロ",
"ariana": "アテナ",
"proton": "ランス",
"petrel": "ラムダ",
"tabitha": "ホムラ",
"courtney": "カガリ",
"shelly": "イズミ",
"matt": "ウシオ",
"mars": "マーズ",
"jupiter": "ジュピター",
"saturn": "サターン",
"zinzolin": "ヴィオ",
"rood": "ロット",
"xerosic": "クセロシキ",
"bryony": "バラ",
"faba": "ザオボー",
"plumeria": "プルメリ",
"oleana": "オリーヴ",
"maxie": "マツブサ",
"archie": "アオギリ",
"cyrus": "アカギ",
"ghetsis": "ゲーチス",
"lysandre": "フラダリ",
"lusamine": "ルザミーネ",
"guzma": "グズマ",
"rose": "ローズ",
"blue_red_double": "グリーンとレッド",
"red_blue_double": "レッドとグリーン",
"tate_liza_double": "フウとラン",
"liza_tate_double": "ランとフウ",
"steven_wallace_double": "ダイゴとミクリ",
"wallace_steven_double": "ミクリとダイゴ",
"alder_iris_double": "アデクとアイリス",
"iris_alder_double": "アイリスとアデク",
"marnie_piers_double": "マリィとネズ",
"piers_marnie_double": "ネズとマリィ"
}

View File

@ -1 +1,38 @@
{} {
"elite_four": "四天王",
"elite_four_female": "四天王",
"gym_leader": "ジムリーダー",
"gym_leader_female": "ジムリーダー",
"gym_leader_double": "ジムリーダーコンビ",
"champion": "チャンピオン",
"champion_female": "チャンピオン",
"champion_double": "チャンピオンコンビ",
"rival": "ライバル",
"professor": "ポケモン博士",
"frontier_brain": "フロンティアブレーン",
"rocket_boss": "ロケット団ボス",
"magma_boss": "マグマ団リーダー",
"aqua_boss": "アクア団リーダー",
"galactic_boss": "ギンガ団ボス",
"plasma_boss": "プラズマ団ボス",
"flare_boss": "フレア団ボス",
"aether_boss": "エーテル代表",
"skull_boss": "スカル団ボス",
"macro_boss": "マクロコスモス社長",
"rocket_admin": "ロケット団幹部",
"rocket_admin_female": "ロケット団幹部",
"magma_admin": "マグマ団幹部",
"magma_admin_female": "マグマロケット団幹部",
"aqua_admin": "アクア団幹部",
"aqua_admin_female": "アクア団幹部",
"galactic_commander": "ギンガ団幹部",
"galactic_commander_female": "ギンガ団幹部",
"plasma_sage": "プラズマ団賢人",
"plasma_admin": "プラズマ団賢人",
"flare_admin": "フレア団幹部",
"flare_admin_female": "フレア団幹部",
"aether_admin": "エーテル支部長",
"skull_admin": "スカル団幹部",
"macro_admin": "マクロコスモス"
}

View File

@ -80,7 +80,7 @@
"100_RIBBONS": { "100_RIBBONS": {
"name": "마스터 리그 챔피언" "name": "마스터 리그 챔피언"
}, },
"TRANSFER_MAX_BATTLE_STAT": { "TRANSFER_MAX_STAT_STAGE": {
"name": "팀워크", "name": "팀워크",
"description": "한 개 이상의 능력치가 최대 랭크일 때 배턴터치 사용" "description": "한 개 이상의 능력치가 최대 랭크일 때 배턴터치 사용"
}, },

View File

@ -1,6 +1,6 @@
{ {
"ending": "@c{smile}오? 이긴거야?@d{96} @c{smile_eclosed}진즉 알았어야 했는데.\n아무튼, 돌아왔구나.\n$@c{smile}다 끝난거야.@d{64} 네가 굴레를 끝장냈어.\n$@c{serious_smile_fists}네 꿈도 이뤄졌고말야.\n진짜로 한 번도 안 졌잖아.\n$@c{neutral}기억하는 건 우리들 뿐일 모양이지만.@d{96}\n그래도, 괜찮지?\n$@c{serious_smile_fists}오늘의 일은\n너와 나의 마음 속에 항상 함께할 거야.\n$@c{smile_eclosed}여기 구경도 충분히 했으니\n이제 집에 가자.\n$@c{serious_smile_fists}되돌아가서, 다시 배틀을 할 수도 있지 않을까?\n네가 원한다면 말야.", "ending": "@c{shock}돌아왔구나?@d{32} 그 말은…@d{96} 이겼어?!\n@c{smile_ehalf}그럴 줄 알았다니까.\n$@c{smile_eclosed}물론… 언제나 느껴왔지.\n@c{smile}끝난 거, 맞지? 이 굴레를 말이야.\n$@c{smile_ehalf}네 꿈도 이뤘고 말이야.\n어떻게 한번도 안 졌대?\n$네가 한 일은 나만 기억하게 될 모양이지만.\n@c{angry_mopen}나, 안 까먹어볼 테니까!\n$@c{smile_wave_wink}농담이야!@d{64} @c{smile}절대 안 잊어버릴 거야.@d{32}\n마음 속엔 쭉 남아있을 수 있게.\n$@c{smile_wave}어쨌든,@d{64} 시간이 좀 늦었어…@d{96}\n이런 곳에서 할 말은 아닌가?\n$집에 가자. @c{smile_wave_wink}아마 내일은,\n추억을 되짚어보기 위한 배틀을 해볼 수 있을 거야.",
"ending_female": "@c{shock}돌아왔구나?@d{32} 그 말은…@d{96} 이겼어?!\n@c{smile_ehalf}그럴 줄 알았다니까.\n$@c{smile_eclosed}물론… 언제나 느껴왔지.\n@c{smile}끝난 거, 맞지? 이 굴레를 말이야.\n$@c{smile_ehalf}네 꿈도 이뤘고 말이야.\n어떻게 한번도 안 졌대?\n$네가 한 일은 나만 기억하게 될 모양이지만.\n@c{angry_mopen}나, 안 까먹어볼 테니까!\n$@c{smile_wave_wink}농담이야!@d{64} @c{smile}절대 안 잊어버릴 거야.@d{32}\n마음 속엔 쭉 남아있을 수 있게.\n$@c{smile_wave}어쨌든,@d{64} 시간이 좀 늦었어…@d{96}\n이런 곳에서 할 말은 아닌가?\n$집에 가자. @c{smile_wave_wink}아마 내일은,\n추억을 되짚어보기 위한 배틀을 해볼 수 있을 거야.", "ending_female": "@c{smile}오? 이긴거야?@d{96} @c{smile_eclosed}진즉 알았어야 했는데.\n아무튼, 돌아왔구나.\n$@c{smile}다 끝난거야.@d{64} 네가 굴레를 끝장냈어.\n$@c{serious_smile_fists}네 꿈도 이뤄졌고말야.\n진짜로 한 번도 안 졌잖아.\n$@c{neutral}기억하는 건 우리들 뿐일 모양이지만.@d{96}\n그래도, 괜찮지?\n$@c{serious_smile_fists}오늘의 일은\n너와 나의 마음 속에 항상 함께할 거야.\n$@c{smile_eclosed}여기 구경도 충분히 했으니\n이제 집에 가자.\n$@c{serious_smile_fists}되돌아가서, 다시 배틀을 할 수도 있지 않을까?\n네가 원한다면 말야.",
"ending_endless": "끝에 도달하신 것을 축하드립니다!\n더 많은 컨텐츠를 기다려주세요.", "ending_endless": "끝에 도달하신 것을 축하드립니다!\n더 많은 컨텐츠를 기다려주세요.",
"ending_name": "Devs" "ending_name": "Devs"
} }

View File

@ -49,8 +49,8 @@
"DoubleBattleChanceBoosterModifierType": { "DoubleBattleChanceBoosterModifierType": {
"description": "{{battleCount}}번의 배틀 동안 더블 배틀이 등장할 확률이 두 배가 된다." "description": "{{battleCount}}번의 배틀 동안 더블 배틀이 등장할 확률이 두 배가 된다."
}, },
"TempBattleStatBoosterModifierType": { "TempStatStageBoosterModifierType": {
"description": "자신의 모든 포켓몬이 5번의 배틀 동안 {{tempBattleStatName}}[[가]] 한 단계 증가한다." "description": "자신의 모든 포켓몬이 5번의 배틀 동안 {{stat}}[[가]] 한 단계 증가한다."
}, },
"AttackTypeBoosterModifierType": { "AttackTypeBoosterModifierType": {
"description": "지니게 하면 {{moveType}}타입 기술의 위력이 20% 상승한다." "description": "지니게 하면 {{moveType}}타입 기술의 위력이 20% 상승한다."
@ -61,8 +61,8 @@
"AllPokemonLevelIncrementModifierType": { "AllPokemonLevelIncrementModifierType": {
"description": "자신의 모든 포켓몬의 레벨이 {{levels}}만큼 상승한다." "description": "자신의 모든 포켓몬의 레벨이 {{levels}}만큼 상승한다."
}, },
"PokemonBaseStatBoosterModifierType": { "BaseStatBoosterModifierType": {
"description": "지니게 하면 {{statName}} 종족값을 10% 올려준다. 개체값이 높을수록 더 많이 누적시킬 수 있다." "description": "지니게 하면 {{stat}} 종족값을 10% 올려준다. 개체값이 높을수록 더 많이 누적시킬 수 있다."
}, },
"AllPokemonFullHpRestoreModifierType": { "AllPokemonFullHpRestoreModifierType": {
"description": "자신의 포켓몬의 HP를 모두 회복한다." "description": "자신의 포켓몬의 HP를 모두 회복한다."
@ -248,6 +248,12 @@
"name": "초점렌즈", "name": "초점렌즈",
"description": "약점이 보이는 렌즈. 지니게 한 포켓몬의 기술이 급소에 맞기 쉬워진다." "description": "약점이 보이는 렌즈. 지니게 한 포켓몬의 기술이 급소에 맞기 쉬워진다."
}, },
"DIRE_HIT": {
"name": "크리티컬커터",
"extra": {
"raises": "급소율"
}
},
"LEEK": { "LEEK": {
"name": "대파", "name": "대파",
"description": "매우 길고 단단한 줄기. 파오리에게 지니게 하면 기술이 급소에 맞기 쉬워진다." "description": "매우 길고 단단한 줄기. 파오리에게 지니게 하면 기술이 급소에 맞기 쉬워진다."
@ -411,25 +417,13 @@
"description": "메타몽에게 지니게 하면 스피드가 올라가는 이상한 가루. 매우 잘고 단단하다." "description": "메타몽에게 지니게 하면 스피드가 올라가는 이상한 가루. 매우 잘고 단단하다."
} }
}, },
"TempBattleStatBoosterItem": { "TempStatStageBoosterItem": {
"x_attack": "플러스파워", "x_attack": "플러스파워",
"x_defense": "디펜드업", "x_defense": "디펜드업",
"x_sp_atk": "스페셜업", "x_sp_atk": "스페셜업",
"x_sp_def": "스페셜가드", "x_sp_def": "스페셜가드",
"x_speed": "스피드업", "x_speed": "스피드업",
"x_accuracy": "잘-맞히기", "x_accuracy": "잘-맞히기"
"dire_hit": "크리티컬커터"
},
"TempBattleStatBoosterStatName": {
"ATK": "공격",
"DEF": "방어",
"SPATK": "특수공격",
"SPDEF": "특수방어",
"SPD": "스피드",
"ACC": "명중률",
"CRIT": "급소율",
"EVA": "회피율",
"DEFAULT": "???"
}, },
"AttackTypeBoosterItem": { "AttackTypeBoosterItem": {
"silk_scarf": "실크스카프", "silk_scarf": "실크스카프",
@ -606,4 +600,4 @@
"FAIRY_MEMORY": "페어리메모리", "FAIRY_MEMORY": "페어리메모리",
"NORMAL_MEMORY": "일반메모리" "NORMAL_MEMORY": "일반메모리"
} }
} }

View File

@ -3,6 +3,10 @@
"cutHpPowerUpMove": "{{pokemonName}}[[는]]\n체력을 깎아서 자신의 기술을 강화했다!", "cutHpPowerUpMove": "{{pokemonName}}[[는]]\n체력을 깎아서 자신의 기술을 강화했다!",
"absorbedElectricity": "{{pokemonName}}는(은)\n전기를 흡수했다!", "absorbedElectricity": "{{pokemonName}}는(은)\n전기를 흡수했다!",
"switchedStatChanges": "{{pokemonName}}[[는]] 상대와 자신의\n능력 변화를 바꿨다!", "switchedStatChanges": "{{pokemonName}}[[는]] 상대와 자신의\n능력 변화를 바꿨다!",
"switchedTwoStatChanges": "{{pokemonName}} 상대와 자신의 {{firstStat}}과 {{secondStat}}의 능력 변화를 바꿨다!",
"switchedStat": "{{pokemonName}} 서로의 {{stat}}를 교체했다!",
"sharedGuard": "{{pokemonName}} 서로의 가드를 셰어했다!",
"sharedPower": "{{pokemonName}} 서로의 파워를 셰어했다!",
"goingAllOutForAttack": "{{pokemonName}}[[는]]\n전력을 다하기 시작했다!", "goingAllOutForAttack": "{{pokemonName}}[[는]]\n전력을 다하기 시작했다!",
"regainedHealth": "{{pokemonName}}[[는]]\n기력을 회복했다!", "regainedHealth": "{{pokemonName}}[[는]]\n기력을 회복했다!",
"keptGoingAndCrashed": "{{pokemonName}}[[는]]\n의욕이 넘쳐서 땅에 부딪쳤다!", "keptGoingAndCrashed": "{{pokemonName}}[[는]]\n의욕이 넘쳐서 땅에 부딪쳤다!",
@ -63,4 +67,4 @@
"swapArenaTags": "{{pokemonName}}[[는]]\n서로의 필드 효과를 교체했다!", "swapArenaTags": "{{pokemonName}}[[는]]\n서로의 필드 효과를 교체했다!",
"exposedMove": "{{pokemonName}}[[는]]\n{{targetPokemonName}}의 정체를 꿰뚫어 보았다!", "exposedMove": "{{pokemonName}}[[는]]\n{{targetPokemonName}}의 정체를 꿰뚫어 보았다!",
"safeguard": "{{targetName}}[[는]] 신비의 베일이 지켜 주고 있다!" "safeguard": "{{targetName}}[[는]] 신비의 베일이 지켜 주고 있다!"
} }

View File

@ -100,7 +100,7 @@
"moveTouchControls": "터치 컨트롤 이동", "moveTouchControls": "터치 컨트롤 이동",
"shopOverlayOpacity": "상점 오버레이 투명도", "shopOverlayOpacity": "상점 오버레이 투명도",
"shopCursorTarget": "상점 커서 위치", "shopCursorTarget": "상점 커서 위치",
"items": "아이템", "rewards": "아이템",
"reroll": "갱신", "reroll": "갱신",
"shop": "상점", "shop": "상점",
"checkTeam": "파티 확인" "checkTeam": "파티 확인"

View File

@ -84,7 +84,7 @@
"100_RIBBONS": { "100_RIBBONS": {
"name": "Fita de Diamante" "name": "Fita de Diamante"
}, },
"TRANSFER_MAX_BATTLE_STAT": { "TRANSFER_MAX_STAT_STAGE": {
"name": "Trabalho em Equipe", "name": "Trabalho em Equipe",
"description": "Use Baton Pass com pelo menos um atributo aumentado ao máximo" "description": "Use Baton Pass com pelo menos um atributo aumentado ao máximo"
}, },
@ -269,4 +269,4 @@
"name": "A torre da derrotA", "name": "A torre da derrotA",
"description": "Complete o desafio da Batalha Inversa.\n.asrevnI ahlataB ad oifased o etelpmoC" "description": "Complete o desafio da Batalha Inversa.\n.asrevnI ahlataB ad oifased o etelpmoC"
} }
} }

View File

@ -1,6 +1,6 @@
{ {
"ending": "@c{smile}Oh? Você venceu?@d{96} @c{smile_eclosed}Acho que eu deveria saber.\nMas, você está de volta agora.\n$@c{smile}Acabou.@d{64} Você quebrou o ciclo.\n$@c{serious_smile_fists}Você também realizou seu sonho, não é?\nVocê não perdeu nenhuma vez.\n$@c{neutral}Eu sou o único que vai lembrar o que você fez.@d{96}\nAcho que está tudo bem, não é?\n$@c{serious_smile_fists}Sua lenda sempre viverá em nossos corações.\n$@c{smile_eclosed}Enfim, já tive o suficiente deste lugar, não é? Vamos para casa.\n$@c{serious_smile_fists}Talvez quando voltarmos, possamos ter outra batalha?\nSe você estiver disposto.", "ending": "@c{shock}Você está de volta?@d{32} Isso significa que…@d{96} você venceu?!\n@c{smile_ehalf}Eu deveria saber que você conseguiria.\n$@c{smile_eclosed}Claro… Eu sempre tive essa sensação.\n@c{smile}Acabou agora, certo? Você quebrou o ciclo.\n$@c{smile_ehalf}Você também realizou seu sonho, não foi?\nVocê não perdeu nenhuma vez.\n$Eu serei a única a lembrar o que você fez.\n@c{angry_mopen}Eu tentarei não esquecer!\n$@c{smile_wave_wink}Brincadeirinha!@d{64} @c{smile}Eu nunca esqueceria.@d{32}\nSua lenda viverá em nossos corações.\n$@c{smile_wave}De qualquer forma,@d{64} está ficando tarde…@d{96} Eu acho?\nÉ difícil dizer neste lugar.\n$Vamos para casa. @c{smile_wave_wink}Talvez amanhã possamos ter outra batalha, pelos velhos tempos?",
"ending_female": "@c{shock}Você está de volta?@d{32} Isso significa que…@d{96} você venceu?!\n@c{smile_ehalf}Eu deveria saber que você conseguiria.\n$@c{smile_eclosed}Claro… Eu sempre tive essa sensação.\n@c{smile}Acabou agora, certo? Você quebrou o ciclo.\n$@c{smile_ehalf}Você também realizou seu sonho, não foi?\nVocê não perdeu nenhuma vez.\n$Eu serei a única a lembrar o que você fez.\n@c{angry_mopen}Eu tentarei não esquecer!\n$@c{smile_wave_wink}Brincadeirinha!@d{64} @c{smile}Eu nunca esqueceria.@d{32}\nSua lenda viverá em nossos corações.\n$@c{smile_wave}De qualquer forma,@d{64} está ficando tarde…@d{96} Eu acho?\nÉ difícil dizer neste lugar.\n$Vamos para casa. @c{smile_wave_wink}Talvez amanhã possamos ter outra batalha, pelos velhos tempos?", "ending_female": "@c{smile}Oh? Você venceu?@d{96} @c{smile_eclosed}Acho que eu deveria saber.\nMas, você está de volta agora.\n$@c{smile}Acabou.@d{64} Você quebrou o ciclo.\n$@c{serious_smile_fists}Você também realizou seu sonho, não é?\nVocê não perdeu nenhuma vez.\n$@c{neutral}Eu sou o único que vai lembrar o que você fez.@d{96}\nAcho que está tudo bem, não é?\n$@c{serious_smile_fists}Sua lenda sempre viverá em nossos corações.\n$@c{smile_eclosed}Enfim, já tive o suficiente deste lugar, não é? Vamos para casa.\n$@c{serious_smile_fists}Talvez quando voltarmos, possamos ter outra batalha?\nSe você estiver disposto.",
"ending_endless": "Parabéns por alcançar o final atual!\nMais conteúdo chegará em breve.", "ending_endless": "Parabéns por alcançar o final atual!\nMais conteúdo chegará em breve.",
"ending_name": "Desenvolvedores" "ending_name": "Desenvolvedores"
} }

View File

@ -49,8 +49,8 @@
"DoubleBattleChanceBoosterModifierType": { "DoubleBattleChanceBoosterModifierType": {
"description": "Dobra as chances de encontrar uma batalha em dupla por {{battleCount}} batalhas." "description": "Dobra as chances de encontrar uma batalha em dupla por {{battleCount}} batalhas."
}, },
"TempBattleStatBoosterModifierType": { "TempStatStageBoosterModifierType": {
"description": "Aumenta o atributo de {{tempBattleStatName}} para todos os membros da equipe por 5 batalhas." "description": "Aumenta o atributo de {{stat}} para todos os membros da equipe por 5 batalhas."
}, },
"AttackTypeBoosterModifierType": { "AttackTypeBoosterModifierType": {
"description": "Aumenta o poder dos ataques do tipo {{moveType}} de um Pokémon em 20%." "description": "Aumenta o poder dos ataques do tipo {{moveType}} de um Pokémon em 20%."
@ -61,8 +61,8 @@
"AllPokemonLevelIncrementModifierType": { "AllPokemonLevelIncrementModifierType": {
"description": "Aumenta em {{levels}} o nível de todos os membros da equipe." "description": "Aumenta em {{levels}} o nível de todos os membros da equipe."
}, },
"PokemonBaseStatBoosterModifierType": { "BaseStatBoosterModifierType": {
"description": "Aumenta o atributo base de {{statName}} em 10%. Quanto maior os IVs, maior o limite de aumento." "description": "Aumenta o atributo base de {{stat}} em 10%. Quanto maior os IVs, maior o limite de aumento."
}, },
"AllPokemonFullHpRestoreModifierType": { "AllPokemonFullHpRestoreModifierType": {
"description": "Restaura totalmente os PS de todos os Pokémon." "description": "Restaura totalmente os PS de todos os Pokémon."
@ -248,6 +248,12 @@
"name": "Lentes de Mira", "name": "Lentes de Mira",
"description": "Estas lentes facilitam o foco em pontos fracos. Aumenta a chance de acerto crítico de quem a segurar." "description": "Estas lentes facilitam o foco em pontos fracos. Aumenta a chance de acerto crítico de quem a segurar."
}, },
"DIRE_HIT": {
"name": "Direto",
"extra": {
"raises": "Chance de Acerto Crítico"
}
},
"LEEK": { "LEEK": {
"name": "Alho-poró", "name": "Alho-poró",
"description": "Esse talo de alho-poró muito longo e rígido aumenta a taxa de acerto crítico dos movimentos do Farfetch'd." "description": "Esse talo de alho-poró muito longo e rígido aumenta a taxa de acerto crítico dos movimentos do Farfetch'd."
@ -411,25 +417,13 @@
"description": "Extremamente fino, porém duro, este pó estranho aumenta o atributo de Velocidade de Ditto." "description": "Extremamente fino, porém duro, este pó estranho aumenta o atributo de Velocidade de Ditto."
} }
}, },
"TempBattleStatBoosterItem": { "TempStatStageBoosterItem": {
"x_attack": "Ataque X", "x_attack": "Ataque X",
"x_defense": "Defesa X", "x_defense": "Defesa X",
"x_sp_atk": "Ataque Esp. X", "x_sp_atk": "Ataque Esp. X",
"x_sp_def": "Defesa Esp. X", "x_sp_def": "Defesa Esp. X",
"x_speed": "Velocidade X", "x_speed": "Velocidade X",
"x_accuracy": "Precisão X", "x_accuracy": "Precisão X"
"dire_hit": "Direto"
},
"TempBattleStatBoosterStatName": {
"ATK": "Ataque",
"DEF": "Defesa",
"SPATK": "Ataque Esp.",
"SPDEF": "Defesa Esp.",
"SPD": "Velocidade",
"ACC": "Precisão",
"CRIT": "Chance de Acerto Crítico",
"EVA": "Evasão",
"DEFAULT": "???"
}, },
"AttackTypeBoosterItem": { "AttackTypeBoosterItem": {
"silk_scarf": "Lenço de Seda", "silk_scarf": "Lenço de Seda",

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