Merge branch 'beta' into refactor-move-phase
|
@ -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"
|
||||||
|
|
|
@ -8,6 +8,8 @@ on:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
- beta
|
- beta
|
||||||
|
merge_group:
|
||||||
|
types: [checks_requested]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
pages:
|
pages:
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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.
|
||||||
|
|
11
index.css
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
13
lefthook.yml
|
@ -2,6 +2,15 @@ pre-commit:
|
||||||
parallel: true
|
parallel: true
|
||||||
commands:
|
commands:
|
||||||
eslint:
|
eslint:
|
||||||
glob: '*.{js,jsx,ts,tsx}'
|
glob: "*.{js,jsx,ts,tsx}"
|
||||||
run: npx eslint --fix {staged_files}
|
run: npx eslint --fix {staged_files}
|
||||||
stage_fixed: true
|
stage_fixed: true
|
||||||
|
skip:
|
||||||
|
- merge
|
||||||
|
- rebase
|
||||||
|
|
||||||
|
pre-push:
|
||||||
|
commands:
|
||||||
|
eslint:
|
||||||
|
glob: "*.{js,ts,jsx,tsx}"
|
||||||
|
run: npx eslint --fix {push_files}
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.3 KiB |
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"1": {
|
||||||
|
"529cc5": "8153c7",
|
||||||
|
"d65a94": "5ad662",
|
||||||
|
"3a73ad": "6b3aad",
|
||||||
|
"bd216b": "21bd69",
|
||||||
|
"5a193a": "195a2a",
|
||||||
|
"193a63": "391963",
|
||||||
|
"295a84": "472984"
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"529cc5": "ffedb6",
|
||||||
|
"d65a94": "e67d2f",
|
||||||
|
"3a73ad": "ebc582",
|
||||||
|
"bd216b": "b35131",
|
||||||
|
"31313a": "3d1519",
|
||||||
|
"5a193a": "752e2e",
|
||||||
|
"193a63": "705040",
|
||||||
|
"295a84": "ad875a",
|
||||||
|
"4a4a52": "57211a"
|
||||||
|
}
|
||||||
|
}
|
Before Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 43 KiB |
|
@ -1691,8 +1691,8 @@
|
||||||
],
|
],
|
||||||
"465": [
|
"465": [
|
||||||
0,
|
0,
|
||||||
2,
|
1,
|
||||||
2
|
1
|
||||||
],
|
],
|
||||||
"466": [
|
"466": [
|
||||||
1,
|
1,
|
||||||
|
@ -3980,6 +3980,11 @@
|
||||||
1,
|
1,
|
||||||
1
|
1
|
||||||
],
|
],
|
||||||
|
"465": [
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1
|
||||||
|
],
|
||||||
"592": [
|
"592": [
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
|
@ -5690,7 +5695,7 @@
|
||||||
"465": [
|
"465": [
|
||||||
0,
|
0,
|
||||||
1,
|
1,
|
||||||
2
|
1
|
||||||
],
|
],
|
||||||
"466": [
|
"466": [
|
||||||
2,
|
2,
|
||||||
|
@ -8008,6 +8013,11 @@
|
||||||
1,
|
1,
|
||||||
1
|
1
|
||||||
],
|
],
|
||||||
|
"465": [
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1
|
||||||
|
],
|
||||||
"592": [
|
"592": [
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
|
|
|
@ -8,5 +8,14 @@
|
||||||
"bd216b": "21bd69",
|
"bd216b": "21bd69",
|
||||||
"31313a": "31313a",
|
"31313a": "31313a",
|
||||||
"d65a94": "5ad662"
|
"d65a94": "5ad662"
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"5a193a": "752e2e",
|
||||||
|
"31313a": "3d1519",
|
||||||
|
"d65a94": "e67d2f",
|
||||||
|
"3a73ad": "ebc582",
|
||||||
|
"295a84": "ad875a",
|
||||||
|
"bd216b": "b35131",
|
||||||
|
"193a63": "705040"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Before Width: | Height: | Size: 34 KiB |
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"1": {
|
||||||
|
"193a63": "391963",
|
||||||
|
"295a84": "472984",
|
||||||
|
"3a73ad": "6b3aad",
|
||||||
|
"000000": "000000",
|
||||||
|
"5a193a": "195a2a",
|
||||||
|
"bd216b": "21bd69",
|
||||||
|
"31313a": "31313a",
|
||||||
|
"d65a94": "5ad662"
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"5a193a": "752e2e",
|
||||||
|
"31313a": "3d1519",
|
||||||
|
"d65a94": "e67d2f",
|
||||||
|
"3a73ad": "ebc582",
|
||||||
|
"295a84": "ad875a",
|
||||||
|
"bd216b": "b35131",
|
||||||
|
"193a63": "705040"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"1": {
|
||||||
|
"529cc5": "8153c7",
|
||||||
|
"d65a94": "5ad662",
|
||||||
|
"3a73ad": "6b3aad",
|
||||||
|
"bd216b": "21bd69",
|
||||||
|
"5a193a": "195a2a",
|
||||||
|
"193a63": "391963",
|
||||||
|
"295a84": "472984"
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"529cc5": "ffedb6",
|
||||||
|
"d65a94": "e67d2f",
|
||||||
|
"3a73ad": "ebc582",
|
||||||
|
"bd216b": "b35131",
|
||||||
|
"31313a": "3d1519",
|
||||||
|
"5a193a": "752e2e",
|
||||||
|
"193a63": "705040",
|
||||||
|
"295a84": "ad875a",
|
||||||
|
"4a4a52": "57211a"
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 179 B |
After Width: | Height: | Size: 172 B |
After Width: | Height: | Size: 205 B |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 179 B |
After Width: | Height: | Size: 172 B |
After Width: | Height: | Size: 205 B |
After Width: | Height: | Size: 261 B |
After Width: | Height: | Size: 261 B |
|
@ -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);
|
||||||
|
@ -854,7 +855,7 @@ export default class BattleScene extends SceneBase {
|
||||||
overrideModifiers(this, false);
|
overrideModifiers(this, false);
|
||||||
overrideHeldItems(this, pokemon, false);
|
overrideHeldItems(this, pokemon, false);
|
||||||
if (boss && !dataSource) {
|
if (boss && !dataSource) {
|
||||||
const secondaryIvs = Utils.getIvsFromId(Utils.randSeedInt(4294967295));
|
const secondaryIvs = Utils.getIvsFromId(Utils.randSeedInt(4294967296));
|
||||||
|
|
||||||
for (let s = 0; s < pokemon.ivs.length; s++) {
|
for (let s = 0; s < pokemon.ivs.length; s++) {
|
||||||
pokemon.ivs[s] = Math.round(Phaser.Math.Linear(Math.min(pokemon.ivs[s], secondaryIvs[s]), Math.max(pokemon.ivs[s], secondaryIvs[s]), 0.75));
|
pokemon.ivs[s] = Math.round(Phaser.Math.Linear(Math.min(pokemon.ivs[s], secondaryIvs[s]), Math.max(pokemon.ivs[s], secondaryIvs[s]), 0.75));
|
||||||
|
@ -960,6 +961,16 @@ export default class BattleScene extends SceneBase {
|
||||||
this.offsetGym = this.gameMode.isClassic && this.getGeneratedOffsetGym();
|
this.offsetGym = this.gameMode.isClassic && this.getGeneratedOffsetGym();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a random number using the current battle's seed
|
||||||
|
*
|
||||||
|
* This calls {@linkcode Battle.randSeedInt}(`scene`, {@linkcode range}, {@linkcode min}) in `src/battle.ts`
|
||||||
|
* which calls {@linkcode Utils.randSeedInt randSeedInt}({@linkcode range}, {@linkcode min}) in `src/utils.ts`
|
||||||
|
*
|
||||||
|
* @param range How large of a range of random numbers to choose from. If {@linkcode range} <= 1, returns {@linkcode min}
|
||||||
|
* @param min The minimum integer to pick, default `0`
|
||||||
|
* @returns A random integer between {@linkcode min} and ({@linkcode min} + {@linkcode range} - 1)
|
||||||
|
*/
|
||||||
randBattleSeedInt(range: integer, min: integer = 0): integer {
|
randBattleSeedInt(range: integer, min: integer = 0): integer {
|
||||||
return this.currentBattle?.randSeedInt(this, range, min);
|
return this.currentBattle?.randSeedInt(this, range, min);
|
||||||
}
|
}
|
||||||
|
@ -973,6 +984,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;
|
||||||
|
|
||||||
|
@ -1110,7 +1122,8 @@ export default class BattleScene extends SceneBase {
|
||||||
doubleTrainer = false;
|
doubleTrainer = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
newTrainer = trainerData !== undefined ? trainerData.toTrainer(this) : new Trainer(this, trainerType, doubleTrainer ? TrainerVariant.DOUBLE : Utils.randSeedInt(2) ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT);
|
const variant = doubleTrainer ? TrainerVariant.DOUBLE : (Utils.randSeedInt(2) ? TrainerVariant.FEMALE : TrainerVariant.DEFAULT);
|
||||||
|
newTrainer = trainerData !== undefined ? trainerData.toTrainer(this) : new Trainer(this, trainerType, variant);
|
||||||
this.field.add(newTrainer);
|
this.field.add(newTrainer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1327,6 +1340,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;
|
||||||
}
|
}
|
||||||
|
@ -2611,7 +2631,7 @@ export default class BattleScene extends SceneBase {
|
||||||
if (mods.length < 1) {
|
if (mods.length < 1) {
|
||||||
return mods;
|
return mods;
|
||||||
}
|
}
|
||||||
const rand = Math.floor(Utils.randSeedInt(mods.length));
|
const rand = Utils.randSeedInt(mods.length);
|
||||||
return [mods[rand], ...shuffleModifiers(mods.filter((_, i) => i !== rand))];
|
return [mods[rand], ...shuffleModifiers(mods.filter((_, i) => i !== rand))];
|
||||||
};
|
};
|
||||||
modifiers = shuffleModifiers(modifiers);
|
modifiers = shuffleModifiers(modifiers);
|
||||||
|
@ -2733,6 +2753,35 @@ export default class BattleScene extends SceneBase {
|
||||||
(window as any).gameInfo = gameInfo;
|
(window as any).gameInfo = gameInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function retrieves the sprite and audio keys for active Pokemon.
|
||||||
|
* Active Pokemon include both enemy and player Pokemon of the current wave.
|
||||||
|
* Note: Questions on garbage collection go to @frutescens
|
||||||
|
* @returns a string array of active sprite and audio keys that should not be deleted
|
||||||
|
*/
|
||||||
|
getActiveKeys(): string[] {
|
||||||
|
const keys: string[] = [];
|
||||||
|
const playerParty = this.getParty();
|
||||||
|
playerParty.forEach(p => {
|
||||||
|
keys.push("pkmn__" + p.species.getSpriteId(p.gender === Gender.FEMALE, p.species.formIndex, p.shiny, p.variant));
|
||||||
|
keys.push("pkmn__" + p.species.getSpriteId(p.gender === Gender.FEMALE, p.species.formIndex, p.shiny, p.variant, true));
|
||||||
|
keys.push("cry/" + p.species.getCryKey(p.species.formIndex));
|
||||||
|
if (p.fusionSpecies && p.getSpeciesForm() !== p.getFusionSpeciesForm()) {
|
||||||
|
keys.push("cry/"+p.getFusionSpeciesForm().getCryKey(p.fusionSpecies.formIndex));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// enemyParty has to be operated on separately from playerParty because playerPokemon =/= enemyPokemon
|
||||||
|
const enemyParty = this.getEnemyParty();
|
||||||
|
enemyParty.forEach(p => {
|
||||||
|
keys.push(p.species.getSpriteKey(p.gender === Gender.FEMALE, p.species.formIndex, p.shiny, p.variant));
|
||||||
|
keys.push("cry/" + p.species.getCryKey(p.species.formIndex));
|
||||||
|
if (p.fusionSpecies && p.getSpeciesForm() !== p.getFusionSpeciesForm()) {
|
||||||
|
keys.push("cry/"+p.getFusionSpeciesForm().getCryKey(p.fusionSpecies.formIndex));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return keys;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialized the 2nd phase of the final boss (e.g. form-change for Eternatus)
|
* Initialized the 2nd phase of the final boss (e.g. form-change for Eternatus)
|
||||||
* @param pokemon The (enemy) pokemon
|
* @param pokemon The (enemy) pokemon
|
||||||
|
|
|
@ -6,7 +6,7 @@ import Trainer, { TrainerVariant } from "./field/trainer";
|
||||||
import { GameMode } from "./game-mode";
|
import { GameMode } from "./game-mode";
|
||||||
import { MoneyMultiplierModifier, PokemonHeldItemModifier } from "./modifier/modifier";
|
import { MoneyMultiplierModifier, PokemonHeldItemModifier } from "./modifier/modifier";
|
||||||
import { PokeballType } from "./data/pokeball";
|
import { PokeballType } from "./data/pokeball";
|
||||||
import {trainerConfigs} from "#app/data/trainer-config";
|
import { trainerConfigs } from "#app/data/trainer-config";
|
||||||
import { ArenaTagType } from "#enums/arena-tag-type";
|
import { ArenaTagType } from "#enums/arena-tag-type";
|
||||||
import { BattleSpec } from "#enums/battle-spec";
|
import { BattleSpec } from "#enums/battle-spec";
|
||||||
import { Moves } from "#enums/moves";
|
import { Moves } from "#enums/moves";
|
||||||
|
@ -31,7 +31,7 @@ export enum BattlerIndex {
|
||||||
|
|
||||||
export interface TurnCommand {
|
export interface TurnCommand {
|
||||||
command: Command;
|
command: Command;
|
||||||
cursor?: integer;
|
cursor?: number;
|
||||||
move?: QueuedMove;
|
move?: QueuedMove;
|
||||||
targets?: BattlerIndex[];
|
targets?: BattlerIndex[];
|
||||||
skip?: boolean;
|
skip?: boolean;
|
||||||
|
@ -39,38 +39,40 @@ export interface TurnCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface TurnCommands {
|
interface TurnCommands {
|
||||||
[key: integer]: TurnCommand | null
|
[key: number]: TurnCommand | null
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class Battle {
|
export default class Battle {
|
||||||
protected gameMode: GameMode;
|
protected gameMode: GameMode;
|
||||||
public waveIndex: integer;
|
public waveIndex: number;
|
||||||
public battleType: BattleType;
|
public battleType: BattleType;
|
||||||
public battleSpec: BattleSpec;
|
public battleSpec: BattleSpec;
|
||||||
public trainer: Trainer | null;
|
public trainer: Trainer | null;
|
||||||
public enemyLevels: integer[] | undefined;
|
public enemyLevels: number[] | undefined;
|
||||||
public enemyParty: EnemyPokemon[];
|
public enemyParty: EnemyPokemon[] = [];
|
||||||
public seenEnemyPartyMemberIds: Set<integer>;
|
public seenEnemyPartyMemberIds: Set<number> = new Set<number>();
|
||||||
public double: boolean;
|
public double: boolean;
|
||||||
public started: boolean;
|
public started: boolean = false;
|
||||||
public enemySwitchCounter: integer;
|
public enemySwitchCounter: number = 0;
|
||||||
public turn: integer;
|
public turn: number = 0;
|
||||||
public turnCommands: TurnCommands;
|
public turnCommands: TurnCommands;
|
||||||
public playerParticipantIds: Set<integer>;
|
public playerParticipantIds: Set<number> = new Set<number>();
|
||||||
public battleScore: integer;
|
public battleScore: number = 0;
|
||||||
public postBattleLoot: PokemonHeldItemModifier[];
|
public postBattleLoot: PokemonHeldItemModifier[] = [];
|
||||||
public escapeAttempts: integer;
|
public escapeAttempts: number = 0;
|
||||||
public lastMove: Moves;
|
public lastMove: Moves;
|
||||||
public battleSeed: string;
|
public battleSeed: string = Utils.randomString(16, true);
|
||||||
private battleSeedState: string | null;
|
private battleSeedState: string | null = null;
|
||||||
public moneyScattered: number;
|
public moneyScattered: number = 0;
|
||||||
public lastUsedPokeball: PokeballType | null;
|
public lastUsedPokeball: PokeballType | null = null;
|
||||||
public playerFaints: number; // The amount of times pokemon on the players side have fainted
|
/** The number of times a Pokemon on the player's side has fainted this battle */
|
||||||
public enemyFaints: number; // The amount of times pokemon on the enemies side have fainted
|
public playerFaints: number = 0;
|
||||||
|
/** The number of times a Pokemon on the enemy's side has fainted this battle */
|
||||||
|
public enemyFaints: number = 0;
|
||||||
|
|
||||||
private rngCounter: integer = 0;
|
private rngCounter: number = 0;
|
||||||
|
|
||||||
constructor(gameMode: GameMode, waveIndex: integer, battleType: BattleType, trainer?: Trainer, double?: boolean) {
|
constructor(gameMode: GameMode, waveIndex: number, battleType: BattleType, trainer?: Trainer, double?: boolean) {
|
||||||
this.gameMode = gameMode;
|
this.gameMode = gameMode;
|
||||||
this.waveIndex = waveIndex;
|
this.waveIndex = waveIndex;
|
||||||
this.battleType = battleType;
|
this.battleType = battleType;
|
||||||
|
@ -79,22 +81,7 @@ export default class Battle {
|
||||||
this.enemyLevels = battleType !== BattleType.TRAINER
|
this.enemyLevels = battleType !== BattleType.TRAINER
|
||||||
? new Array(double ? 2 : 1).fill(null).map(() => this.getLevelForWave())
|
? new Array(double ? 2 : 1).fill(null).map(() => this.getLevelForWave())
|
||||||
: trainer?.getPartyLevels(this.waveIndex);
|
: trainer?.getPartyLevels(this.waveIndex);
|
||||||
this.enemyParty = [];
|
this.double = double ?? false;
|
||||||
this.seenEnemyPartyMemberIds = new Set<integer>();
|
|
||||||
this.double = !!double;
|
|
||||||
this.enemySwitchCounter = 0;
|
|
||||||
this.turn = 0;
|
|
||||||
this.playerParticipantIds = new Set<integer>();
|
|
||||||
this.battleScore = 0;
|
|
||||||
this.postBattleLoot = [];
|
|
||||||
this.escapeAttempts = 0;
|
|
||||||
this.started = false;
|
|
||||||
this.battleSeed = Utils.randomString(16, true);
|
|
||||||
this.battleSeedState = null;
|
|
||||||
this.moneyScattered = 0;
|
|
||||||
this.lastUsedPokeball = null;
|
|
||||||
this.playerFaints = 0;
|
|
||||||
this.enemyFaints = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private initBattleSpec(): void {
|
private initBattleSpec(): void {
|
||||||
|
@ -105,7 +92,7 @@ export default class Battle {
|
||||||
this.battleSpec = spec;
|
this.battleSpec = spec;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getLevelForWave(): integer {
|
private getLevelForWave(): number {
|
||||||
const levelWaveIndex = this.gameMode.getWaveForDifficulty(this.waveIndex);
|
const levelWaveIndex = this.gameMode.getWaveForDifficulty(this.waveIndex);
|
||||||
const baseLevel = 1 + levelWaveIndex / 2 + Math.pow(levelWaveIndex / 25, 2);
|
const baseLevel = 1 + levelWaveIndex / 2 + Math.pow(levelWaveIndex / 25, 2);
|
||||||
const bossMultiplier = 1.2;
|
const bossMultiplier = 1.2;
|
||||||
|
@ -138,7 +125,7 @@ export default class Battle {
|
||||||
return rand / value;
|
return rand / value;
|
||||||
}
|
}
|
||||||
|
|
||||||
getBattlerCount(): integer {
|
getBattlerCount(): number {
|
||||||
return this.double ? 2 : 1;
|
return this.double ? 2 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -367,7 +354,13 @@ export default class Battle {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
randSeedInt(scene: BattleScene, range: integer, min: integer = 0): integer {
|
/**
|
||||||
|
* Generates a random number using the current battle's seed. Calls {@linkcode Utils.randSeedInt}
|
||||||
|
* @param range How large of a range of random numbers to choose from. If {@linkcode range} <= 1, returns {@linkcode min}
|
||||||
|
* @param min The minimum integer to pick, default `0`
|
||||||
|
* @returns A random integer between {@linkcode min} and ({@linkcode min} + {@linkcode range} - 1)
|
||||||
|
*/
|
||||||
|
randSeedInt(scene: BattleScene, range: number, min: number = 0): number {
|
||||||
if (range <= 1) {
|
if (range <= 1) {
|
||||||
return min;
|
return min;
|
||||||
}
|
}
|
||||||
|
@ -392,7 +385,7 @@ export default class Battle {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class FixedBattle extends Battle {
|
export class FixedBattle extends Battle {
|
||||||
constructor(scene: BattleScene, waveIndex: integer, config: FixedBattleConfig) {
|
constructor(scene: BattleScene, waveIndex: number, config: FixedBattleConfig) {
|
||||||
super(scene.gameMode, waveIndex, config.battleType, config.battleType === BattleType.TRAINER ? config.getTrainer(scene) : undefined, config.double);
|
super(scene.gameMode, waveIndex, config.battleType, config.battleType === BattleType.TRAINER ? config.getTrainer(scene) : undefined, config.double);
|
||||||
if (config.getEnemyParty) {
|
if (config.getEnemyParty) {
|
||||||
this.enemyParty = config.getEnemyParty(scene);
|
this.enemyParty = config.getEnemyParty(scene);
|
||||||
|
@ -408,7 +401,7 @@ export class FixedBattleConfig {
|
||||||
public double: boolean;
|
public double: boolean;
|
||||||
public getTrainer: GetTrainerFunc;
|
public getTrainer: GetTrainerFunc;
|
||||||
public getEnemyParty: GetEnemyPartyFunc;
|
public getEnemyParty: GetEnemyPartyFunc;
|
||||||
public seedOffsetWaveIndex: integer;
|
public seedOffsetWaveIndex: number;
|
||||||
|
|
||||||
setBattleType(battleType: BattleType): FixedBattleConfig {
|
setBattleType(battleType: BattleType): FixedBattleConfig {
|
||||||
this.battleType = battleType;
|
this.battleType = battleType;
|
||||||
|
@ -430,7 +423,7 @@ export class FixedBattleConfig {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
setSeedOffsetWave(seedOffsetWaveIndex: integer): FixedBattleConfig {
|
setSeedOffsetWave(seedOffsetWaveIndex: number): FixedBattleConfig {
|
||||||
this.seedOffsetWaveIndex = seedOffsetWaveIndex;
|
this.seedOffsetWaveIndex = seedOffsetWaveIndex;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -476,7 +469,7 @@ function getRandomTrainerFunc(trainerPool: (TrainerType | TrainerType[])[], rand
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FixedBattleConfigs {
|
export interface FixedBattleConfigs {
|
||||||
[key: integer]: FixedBattleConfig
|
[key: number]: FixedBattleConfig
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Youngster/Lass on 5
|
* Youngster/Lass on 5
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 });
|
|
||||||
}
|
|
|
@ -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 {
|
||||||
|
@ -97,6 +98,127 @@ export interface TerrainBattlerTag {
|
||||||
terrainTypes: TerrainType[];
|
terrainTypes: TerrainType[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for tags that restrict the usage of moves. This effect is generally referred to as "disabling" a move
|
||||||
|
* in-game. This is not to be confused with {@linkcode Moves.DISABLE}.
|
||||||
|
*
|
||||||
|
* Descendants can override {@linkcode isMoveRestricted} to restrict moves that
|
||||||
|
* match a condition. A restricted move gets cancelled before it is used. Players and enemies should not be allowed
|
||||||
|
* to select restricted moves.
|
||||||
|
*/
|
||||||
|
export abstract class MoveRestrictionBattlerTag extends BattlerTag {
|
||||||
|
constructor(tagType: BattlerTagType, turnCount: integer, sourceMove?: Moves, sourceId?: integer) {
|
||||||
|
super(tagType, [ BattlerTagLapseType.PRE_MOVE, BattlerTagLapseType.TURN_END ], turnCount, sourceMove, sourceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
override lapse(pokemon: Pokemon, lapseType: BattlerTagLapseType): boolean {
|
||||||
|
if (lapseType === BattlerTagLapseType.PRE_MOVE) {
|
||||||
|
// Cancel the affected pokemon's selected move
|
||||||
|
const phase = pokemon.scene.getCurrentPhase() as MovePhase;
|
||||||
|
const move = phase.move;
|
||||||
|
|
||||||
|
if (this.isMoveRestricted(move.moveId)) {
|
||||||
|
pokemon.scene.queueMessage(this.interruptedText(pokemon, move.moveId));
|
||||||
|
phase.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.lapse(pokemon, lapseType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether this tag is restricting a move.
|
||||||
|
*
|
||||||
|
* @param {Moves} move {@linkcode Moves} ID to check restriction for.
|
||||||
|
* @returns {boolean} `true` if the move is restricted by this tag, otherwise `false`.
|
||||||
|
*/
|
||||||
|
abstract isMoveRestricted(move: Moves): boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the text to display when the player attempts to select a move that is restricted by this tag.
|
||||||
|
*
|
||||||
|
* @param {Pokemon} pokemon {@linkcode Pokemon} for which the player is attempting to select the restricted move
|
||||||
|
* @param {Moves} move {@linkcode Moves} ID of the move that is having its selection denied
|
||||||
|
* @returns {string} text to display when the player attempts to select the restricted move
|
||||||
|
*/
|
||||||
|
abstract selectionDeniedText(pokemon: Pokemon, move: Moves): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the text to display when a move's execution is prevented as a result of the restriction.
|
||||||
|
* Because restriction effects also prevent selection of the move, this situation can only arise if a
|
||||||
|
* pokemon first selects a move, then gets outsped by a pokemon using a move that restricts the selected move.
|
||||||
|
*
|
||||||
|
* @param {Pokemon} pokemon {@linkcode Pokemon} attempting to use the restricted move
|
||||||
|
* @param {Moves} move {@linkcode Moves} ID of the move being interrupted
|
||||||
|
* @returns {string} text to display when the move is interrupted
|
||||||
|
*/
|
||||||
|
abstract interruptedText(pokemon: Pokemon, move: Moves): string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tag representing the "disabling" effect performed by {@linkcode Moves.DISABLE} and {@linkcode Abilities.CURSED_BODY}.
|
||||||
|
* When the tag is added, the last-used move of the tag holder is set as the disabled move.
|
||||||
|
*/
|
||||||
|
export class DisabledTag extends MoveRestrictionBattlerTag {
|
||||||
|
/** The move being disabled. Gets set when {@linkcode onAdd} is called for this tag. */
|
||||||
|
private moveId: Moves = Moves.NONE;
|
||||||
|
|
||||||
|
constructor(sourceId: number) {
|
||||||
|
super(BattlerTagType.DISABLED, 4, Moves.DISABLE, sourceId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
override isMoveRestricted(move: Moves): boolean {
|
||||||
|
return move === this.moveId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @override
|
||||||
|
*
|
||||||
|
* Ensures that move history exists on `pokemon` and has a valid move. If so, sets the {@link moveId} and shows a message.
|
||||||
|
* Otherwise the move ID will not get assigned and this tag will get removed next turn.
|
||||||
|
*/
|
||||||
|
override onAdd(pokemon: Pokemon): void {
|
||||||
|
super.onAdd(pokemon);
|
||||||
|
|
||||||
|
const move = pokemon.getLastXMoves()
|
||||||
|
.find(m => m.move !== Moves.NONE && m.move !== Moves.STRUGGLE && !m.virtual);
|
||||||
|
if (move === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.moveId = move.move;
|
||||||
|
|
||||||
|
pokemon.scene.queueMessage(i18next.t("battlerTags:disabledOnAdd", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[this.moveId].name }));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
override onRemove(pokemon: Pokemon): void {
|
||||||
|
super.onRemove(pokemon);
|
||||||
|
|
||||||
|
pokemon.scene.queueMessage(i18next.t("battlerTags:disabledLapse", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[this.moveId].name }));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
override selectionDeniedText(pokemon: Pokemon, move: Moves): string {
|
||||||
|
return i18next.t("battle:moveDisabled", { moveName: allMoves[move].name });
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
override interruptedText(pokemon: Pokemon, move: Moves): string {
|
||||||
|
return i18next.t("battle:disableInterruptedMove", { pokemonNameWithAffix: getPokemonNameWithAffix(pokemon), moveName: allMoves[move].name });
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
override loadTag(source: BattlerTag | any): void {
|
||||||
|
super.loadTag(source);
|
||||||
|
this.moveId = source.moveId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BattlerTag that represents the "recharge" effects of moves like Hyper Beam.
|
* BattlerTag that represents the "recharge" effects of moves like Hyper Beam.
|
||||||
*/
|
*/
|
||||||
|
@ -207,7 +329,7 @@ export class ShellTrapTag extends BattlerTag {
|
||||||
|
|
||||||
export class TrappedTag extends BattlerTag {
|
export class TrappedTag extends BattlerTag {
|
||||||
constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType, turnCount: number, sourceMove: Moves, sourceId: number) {
|
constructor(tagType: BattlerTagType, lapseType: BattlerTagLapseType, turnCount: number, sourceMove: Moves, sourceId: number) {
|
||||||
super(tagType, lapseType, turnCount, sourceMove, sourceId);
|
super(tagType, lapseType, turnCount, sourceMove, sourceId, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
canAdd(pokemon: Pokemon): boolean {
|
canAdd(pokemon: Pokemon): boolean {
|
||||||
|
@ -327,7 +449,7 @@ export class InterruptedTag extends BattlerTag {
|
||||||
*/
|
*/
|
||||||
export class ConfusedTag extends BattlerTag {
|
export class ConfusedTag extends BattlerTag {
|
||||||
constructor(turnCount: number, sourceMove: Moves) {
|
constructor(turnCount: number, sourceMove: Moves) {
|
||||||
super(BattlerTagType.CONFUSED, BattlerTagLapseType.MOVE, turnCount, sourceMove);
|
super(BattlerTagType.CONFUSED, BattlerTagLapseType.MOVE, turnCount, sourceMove, undefined, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
canAdd(pokemon: Pokemon): boolean {
|
canAdd(pokemon: Pokemon): boolean {
|
||||||
|
@ -362,9 +484,9 @@ 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.randSeedIntRange(85, 100) / 100));
|
||||||
pokemon.scene.queueMessage(i18next.t("battlerTags:confusedLapseHurtItself"));
|
pokemon.scene.queueMessage(i18next.t("battlerTags:confusedLapseHurtItself"));
|
||||||
pokemon.damageAndUpdate(damage);
|
pokemon.damageAndUpdate(damage);
|
||||||
pokemon.battleData.hitCount++;
|
pokemon.battleData.hitCount++;
|
||||||
|
@ -387,7 +509,7 @@ export class ConfusedTag extends BattlerTag {
|
||||||
*/
|
*/
|
||||||
export class DestinyBondTag extends BattlerTag {
|
export class DestinyBondTag extends BattlerTag {
|
||||||
constructor(sourceMove: Moves, sourceId: number) {
|
constructor(sourceMove: Moves, sourceId: number) {
|
||||||
super(BattlerTagType.DESTINY_BOND, BattlerTagLapseType.PRE_MOVE, 1, sourceMove, sourceId);
|
super(BattlerTagType.DESTINY_BOND, BattlerTagLapseType.PRE_MOVE, 1, sourceMove, sourceId, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -506,7 +628,7 @@ export class SeedTag extends BattlerTag {
|
||||||
private sourceIndex: number;
|
private sourceIndex: number;
|
||||||
|
|
||||||
constructor(sourceId: number) {
|
constructor(sourceId: number) {
|
||||||
super(BattlerTagType.SEEDED, BattlerTagLapseType.TURN_END, 1, Moves.LEECH_SEED, sourceId);
|
super(BattlerTagType.SEEDED, BattlerTagLapseType.TURN_END, 1, Moves.LEECH_SEED, sourceId, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -767,7 +889,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 +899,7 @@ export class OctolockTag extends TrappedTag {
|
||||||
|
|
||||||
export class AquaRingTag extends BattlerTag {
|
export class AquaRingTag extends BattlerTag {
|
||||||
constructor() {
|
constructor() {
|
||||||
super(BattlerTagType.AQUA_RING, BattlerTagLapseType.TURN_END, 1, Moves.AQUA_RING, undefined);
|
super(BattlerTagType.AQUA_RING, BattlerTagLapseType.TURN_END, 1, Moves.AQUA_RING, undefined, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
onAdd(pokemon: Pokemon): void {
|
onAdd(pokemon: Pokemon): void {
|
||||||
|
@ -809,7 +931,7 @@ export class AquaRingTag extends BattlerTag {
|
||||||
/** Tag used to allow moves that interact with {@link Moves.MINIMIZE} to function */
|
/** Tag used to allow moves that interact with {@link Moves.MINIMIZE} to function */
|
||||||
export class MinimizeTag extends BattlerTag {
|
export class MinimizeTag extends BattlerTag {
|
||||||
constructor() {
|
constructor() {
|
||||||
super(BattlerTagType.MINIMIZED, BattlerTagLapseType.TURN_END, 1, Moves.MINIMIZE, undefined);
|
super(BattlerTagType.MINIMIZED, BattlerTagLapseType.TURN_END, 1, Moves.MINIMIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
canAdd(pokemon: Pokemon): boolean {
|
canAdd(pokemon: Pokemon): boolean {
|
||||||
|
@ -1093,7 +1215,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 +1232,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 +1243,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 +1329,7 @@ export class SturdyTag extends BattlerTag {
|
||||||
|
|
||||||
export class PerishSongTag extends BattlerTag {
|
export class PerishSongTag extends BattlerTag {
|
||||||
constructor(turnCount: number) {
|
constructor(turnCount: number) {
|
||||||
super(BattlerTagType.PERISH_SONG, BattlerTagLapseType.TURN_END, turnCount, Moves.PERISH_SONG);
|
super(BattlerTagType.PERISH_SONG, BattlerTagLapseType.TURN_END, turnCount, Moves.PERISH_SONG, undefined, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
canAdd(pokemon: Pokemon): boolean {
|
canAdd(pokemon: Pokemon): boolean {
|
||||||
|
@ -1263,7 +1385,7 @@ export class AbilityBattlerTag extends BattlerTag {
|
||||||
public ability: Abilities;
|
public ability: Abilities;
|
||||||
|
|
||||||
constructor(tagType: BattlerTagType, ability: Abilities, lapseType: BattlerTagLapseType, turnCount: number) {
|
constructor(tagType: BattlerTagType, ability: Abilities, lapseType: BattlerTagLapseType, turnCount: number) {
|
||||||
super(tagType, lapseType, turnCount, undefined);
|
super(tagType, lapseType, turnCount);
|
||||||
|
|
||||||
this.ability = ability;
|
this.ability = ability;
|
||||||
}
|
}
|
||||||
|
@ -1348,11 +1470,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 +1491,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 +1561,7 @@ export class TypeImmuneTag extends BattlerTag {
|
||||||
public immuneType: Type;
|
public immuneType: Type;
|
||||||
|
|
||||||
constructor(tagType: BattlerTagType, sourceMove: Moves, immuneType: Type, length: number = 1) {
|
constructor(tagType: BattlerTagType, sourceMove: Moves, immuneType: Type, length: number = 1) {
|
||||||
super(tagType, BattlerTagLapseType.TURN_END, length, sourceMove);
|
super(tagType, BattlerTagLapseType.TURN_END, length, sourceMove, undefined, true);
|
||||||
|
|
||||||
this.immuneType = immuneType;
|
this.immuneType = immuneType;
|
||||||
}
|
}
|
||||||
|
@ -1504,7 +1625,7 @@ export class TypeBoostTag extends BattlerTag {
|
||||||
|
|
||||||
export class CritBoostTag extends BattlerTag {
|
export class CritBoostTag extends BattlerTag {
|
||||||
constructor(tagType: BattlerTagType, sourceMove: Moves) {
|
constructor(tagType: BattlerTagType, sourceMove: Moves) {
|
||||||
super(tagType, BattlerTagLapseType.TURN_END, 1, sourceMove);
|
super(tagType, BattlerTagLapseType.TURN_END, 1, sourceMove, undefined, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
onAdd(pokemon: Pokemon): void {
|
onAdd(pokemon: Pokemon): void {
|
||||||
|
@ -1596,7 +1717,7 @@ export class CursedTag extends BattlerTag {
|
||||||
private sourceIndex: number;
|
private sourceIndex: number;
|
||||||
|
|
||||||
constructor(sourceId: number) {
|
constructor(sourceId: number) {
|
||||||
super(BattlerTagType.CURSED, BattlerTagLapseType.TURN_END, 1, Moves.CURSE, sourceId);
|
super(BattlerTagType.CURSED, BattlerTagLapseType.TURN_END, 1, Moves.CURSE, sourceId, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1714,25 +1835,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 +1861,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 +1882,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 +1898,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 +2048,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:
|
||||||
|
@ -1995,6 +2116,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: number, source
|
||||||
return new StockpilingTag(sourceMove);
|
return new StockpilingTag(sourceMove);
|
||||||
case BattlerTagType.OCTOLOCK:
|
case BattlerTagType.OCTOLOCK:
|
||||||
return new OctolockTag(sourceId);
|
return new OctolockTag(sourceId);
|
||||||
|
case BattlerTagType.DISABLED:
|
||||||
|
return new DisabledTag(sourceId);
|
||||||
case BattlerTagType.IGNORE_GHOST:
|
case BattlerTagType.IGNORE_GHOST:
|
||||||
return new ExposedTag(tagType, sourceMove, Type.GHOST, [Type.NORMAL, Type.FIGHTING]);
|
return new ExposedTag(tagType, sourceMove, Type.GHOST, [Type.NORMAL, Type.FIGHTING]);
|
||||||
case BattlerTagType.IGNORE_DARK:
|
case BattlerTagType.IGNORE_DARK:
|
||||||
|
|
|
@ -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) => {
|
||||||
|
|
|
@ -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 ],
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
142
src/data/egg.ts
|
@ -15,7 +15,7 @@ export const EGG_SEED = 1073741824;
|
||||||
// Rates for specific random properties in 1/x
|
// Rates for specific random properties in 1/x
|
||||||
const DEFAULT_SHINY_RATE = 128;
|
const DEFAULT_SHINY_RATE = 128;
|
||||||
const GACHA_SHINY_UP_SHINY_RATE = 64;
|
const GACHA_SHINY_UP_SHINY_RATE = 64;
|
||||||
const SAME_SPECIES_EGG_SHINY_RATE = 24;
|
const SAME_SPECIES_EGG_SHINY_RATE = 12;
|
||||||
const SAME_SPECIES_EGG_HA_RATE = 8;
|
const SAME_SPECIES_EGG_HA_RATE = 8;
|
||||||
const MANAPHY_EGG_MANAPHY_RATE = 8;
|
const MANAPHY_EGG_MANAPHY_RATE = 8;
|
||||||
const GACHA_EGG_HA_RATE = 192;
|
const GACHA_EGG_HA_RATE = 192;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
868
src/data/move.ts
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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";
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -64,6 +64,7 @@ export enum BattlerTagType {
|
||||||
STOCKPILING = "STOCKPILING",
|
STOCKPILING = "STOCKPILING",
|
||||||
RECEIVE_DOUBLE_DAMAGE = "RECEIVE_DOUBLE_DAMAGE",
|
RECEIVE_DOUBLE_DAMAGE = "RECEIVE_DOUBLE_DAMAGE",
|
||||||
ALWAYS_GET_HIT = "ALWAYS_GET_HIT",
|
ALWAYS_GET_HIT = "ALWAYS_GET_HIT",
|
||||||
|
DISABLED = "DISABLED",
|
||||||
IGNORE_GHOST = "IGNORE_GHOST",
|
IGNORE_GHOST = "IGNORE_GHOST",
|
||||||
IGNORE_DARK = "IGNORE_DARK",
|
IGNORE_DARK = "IGNORE_DARK",
|
||||||
GULP_MISSILE_ARROKUDA = "GULP_MISSILE_ARROKUDA",
|
GULP_MISSILE_ARROKUDA = "GULP_MISSILE_ARROKUDA",
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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`;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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, MoveRestrictionBattlerTag, 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.
|
||||||
|
@ -1623,7 +1720,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.fusionSpecies = this.scene.randomSpecies(this.scene.currentBattle?.waveIndex || 0, this.level, false, filter, true);
|
this.fusionSpecies = this.scene.randomSpecies(this.scene.currentBattle?.waveIndex || 0, this.level, false, filter, true);
|
||||||
this.fusionAbilityIndex = (this.fusionSpecies.abilityHidden && hasHiddenAbility ? this.fusionSpecies.ability2 ? 2 : 1 : this.fusionSpecies.ability2 ? randAbilityIndex : 0);
|
this.fusionAbilityIndex = (this.fusionSpecies.abilityHidden && hasHiddenAbility ? 2 : this.fusionSpecies.ability2 !== this.fusionSpecies.ability1 ? randAbilityIndex : 0);
|
||||||
this.fusionShiny = this.shiny;
|
this.fusionShiny = this.shiny;
|
||||||
this.fusionVariant = this.variant;
|
this.fusionVariant = this.variant;
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -2155,7 +2278,7 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||||
|
|
||||||
if (!isTypeImmune) {
|
if (!isTypeImmune) {
|
||||||
const levelMultiplier = (2 * source.level / 5 + 2);
|
const levelMultiplier = (2 * source.level / 5 + 2);
|
||||||
const randomMultiplier = ((this.scene.randBattleSeedInt(16) + 85) / 100);
|
const randomMultiplier = (this.randSeedIntRange(85, 100) / 100);
|
||||||
damage.value = Utils.toDmgValue((((levelMultiplier * power * sourceAtk.value / targetDef.value) / 50) + 2)
|
damage.value = Utils.toDmgValue((((levelMultiplier * power * sourceAtk.value / targetDef.value) / 50) + 2)
|
||||||
* stabMultiplier.value
|
* stabMultiplier.value
|
||||||
* typeMultiplier
|
* typeMultiplier
|
||||||
|
@ -2527,27 +2650,53 @@ 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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether the given move is currently disabled for this Pokemon.
|
||||||
|
*
|
||||||
|
* @param {Moves} moveId {@linkcode Moves} ID of the move to check
|
||||||
|
* @returns {boolean} `true` if the move is disabled for this Pokemon, otherwise `false`
|
||||||
|
*
|
||||||
|
* @see {@linkcode MoveRestrictionBattlerTag}
|
||||||
|
*/
|
||||||
|
isMoveRestricted(moveId: Moves): boolean {
|
||||||
|
return this.getRestrictingTag(moveId) !== null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the {@link MoveRestrictionBattlerTag} that is restricting a move, if it exists.
|
||||||
|
*
|
||||||
|
* @param {Moves} moveId {@linkcode Moves} ID of the move to check
|
||||||
|
* @returns {MoveRestrictionBattlerTag | null} the first tag on this Pokemon that restricts the move, or `null` if the move is not restricted.
|
||||||
|
*/
|
||||||
|
getRestrictingTag(moveId: Moves): MoveRestrictionBattlerTag | null {
|
||||||
|
for (const tag of this.findTags(t => t instanceof MoveRestrictionBattlerTag)) {
|
||||||
|
if ((tag as MoveRestrictionBattlerTag).isMoveRestricted(moveId)) {
|
||||||
|
return tag as MoveRestrictionBattlerTag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
getMoveHistory(): TurnMove[] {
|
getMoveHistory(): TurnMove[] {
|
||||||
return this.battleSummonData.moveHistory;
|
return this.battleSummonData.moveHistory;
|
||||||
}
|
}
|
||||||
|
@ -3299,12 +3448,30 @@ export default abstract class Pokemon extends Phaser.GameObjects.Container {
|
||||||
fusionCanvas.remove();
|
fusionCanvas.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a random number using the current battle's seed, or the global seed if `this.scene.currentBattle` is falsy
|
||||||
|
* <!-- @import "../battle".Battle -->
|
||||||
|
* This calls either {@linkcode BattleScene.randBattleSeedInt}({@linkcode range}, {@linkcode min}) in `src/battle-scene.ts`
|
||||||
|
* which calls {@linkcode Battle.randSeedInt}(`scene`, {@linkcode range}, {@linkcode min}) in `src/battle.ts`
|
||||||
|
* which calls {@linkcode Utils.randSeedInt randSeedInt}({@linkcode range}, {@linkcode min}) in `src/utils.ts`,
|
||||||
|
* or it directly calls {@linkcode Utils.randSeedInt randSeedInt}({@linkcode range}, {@linkcode min}) in `src/utils.ts` if there is no current battle
|
||||||
|
*
|
||||||
|
* @param range How large of a range of random numbers to choose from. If {@linkcode range} <= 1, returns {@linkcode min}
|
||||||
|
* @param min The minimum integer to pick, default `0`
|
||||||
|
* @returns A random integer between {@linkcode min} and ({@linkcode min} + {@linkcode range} - 1)
|
||||||
|
*/
|
||||||
randSeedInt(range: integer, min: integer = 0): integer {
|
randSeedInt(range: integer, min: integer = 0): integer {
|
||||||
return this.scene.currentBattle
|
return this.scene.currentBattle
|
||||||
? this.scene.randBattleSeedInt(range, min)
|
? this.scene.randBattleSeedInt(range, min)
|
||||||
: Utils.randSeedInt(range, min);
|
: Utils.randSeedInt(range, min);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a random number using the current battle's seed, or the global seed if `this.scene.currentBattle` is falsy
|
||||||
|
* @param min The minimum integer to generate
|
||||||
|
* @param max The maximum integer to generate
|
||||||
|
* @returns a random integer between {@linkcode min} and {@linkcode max} inclusive
|
||||||
|
*/
|
||||||
randSeedIntRange(min: integer, max: integer): integer {
|
randSeedIntRange(min: integer, max: integer): integer {
|
||||||
return this.randSeedInt((max - min) + 1, min);
|
return this.randSeedInt((max - min) + 1, min);
|
||||||
}
|
}
|
||||||
|
@ -3357,6 +3524,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 +3548,7 @@ export class PlayerPokemon extends Pokemon {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.generateCompatibleTms();
|
this.generateCompatibleTms();
|
||||||
|
this.usedTms = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
initBattleInfo(): void {
|
initBattleInfo(): void {
|
||||||
|
@ -3638,6 +3807,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 +3889,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 +4349,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 +4392,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,10 +4501,8 @@ 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 disabledTurns: number = 0;
|
|
||||||
public tags: BattlerTag[] = [];
|
public tags: BattlerTag[] = [];
|
||||||
public abilitySuppressed: boolean = false;
|
public abilitySuppressed: boolean = false;
|
||||||
public abilitiesApplied: Abilities[] = [];
|
public abilitiesApplied: Abilities[] = [];
|
||||||
|
@ -4344,7 +4512,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 +4543,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 {
|
||||||
|
@ -4415,7 +4583,7 @@ export type DamageResult = HitResult.EFFECTIVE | HitResult.SUPER_EFFECTIVE | Hit
|
||||||
* It links to {@linkcode Move} class via the move ID.
|
* It links to {@linkcode Move} class via the move ID.
|
||||||
* Compared to {@linkcode Move}, this class also tracks if a move has received.
|
* Compared to {@linkcode Move}, this class also tracks if a move has received.
|
||||||
* PP Ups, amount of PP used, and things like that.
|
* PP Ups, amount of PP used, and things like that.
|
||||||
* @see {@linkcode isUsable} - checks if move is disabled, out of PP, or not implemented.
|
* @see {@linkcode isUsable} - checks if move is restricted, out of PP, or not implemented.
|
||||||
* @see {@linkcode getMove} - returns {@linkcode Move} object by looking it up via ID.
|
* @see {@linkcode getMove} - returns {@linkcode Move} object by looking it up via ID.
|
||||||
* @see {@linkcode usePp} - removes a point of PP from the move.
|
* @see {@linkcode usePp} - removes a point of PP from the move.
|
||||||
* @see {@linkcode getMovePp} - returns amount of PP a move currently has.
|
* @see {@linkcode getMovePp} - returns amount of PP a move currently has.
|
||||||
|
@ -4435,11 +4603,25 @@ export class PokemonMove {
|
||||||
this.virtual = !!virtual;
|
this.virtual = !!virtual;
|
||||||
}
|
}
|
||||||
|
|
||||||
isUsable(pokemon: Pokemon, ignorePp?: boolean): boolean {
|
/**
|
||||||
if (this.moveId && pokemon.summonData?.disabledMove === this.moveId) {
|
* Checks whether the move can be selected or performed by a Pokemon, without consideration for the move's targets.
|
||||||
|
* The move is unusable if it is out of PP, restricted by an effect, or unimplemented.
|
||||||
|
*
|
||||||
|
* @param {Pokemon} pokemon {@linkcode Pokemon} that would be using this move
|
||||||
|
* @param {boolean} ignorePp If `true`, skips the PP check
|
||||||
|
* @param {boolean} ignoreRestrictionTags If `true`, skips the check for move restriction tags (see {@link MoveRestrictionBattlerTag})
|
||||||
|
* @returns `true` if the move can be selected and used by the Pokemon, otherwise `false`.
|
||||||
|
*/
|
||||||
|
isUsable(pokemon: Pokemon, ignorePp?: boolean, ignoreRestrictionTags?: boolean): boolean {
|
||||||
|
if (this.moveId && !ignoreRestrictionTags && pokemon.isMoveRestricted(this.moveId)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return (ignorePp || this.ppUsed < this.getMovePp() || this.getMove().pp === -1) && !this.getMove().name.endsWith(" (N)");
|
|
||||||
|
if (this.getMove().name.endsWith(" (N)")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (ignorePp || this.ppUsed < this.getMovePp() || this.getMove().pp === -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
getMove(): Move {
|
getMove(): Move {
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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");
|
||||||
|
@ -162,6 +165,7 @@ export class LoadingScene extends SceneBase {
|
||||||
this.loadImage("saving_icon", "ui");
|
this.loadImage("saving_icon", "ui");
|
||||||
this.loadImage("discord", "ui");
|
this.loadImage("discord", "ui");
|
||||||
this.loadImage("google", "ui");
|
this.loadImage("google", "ui");
|
||||||
|
this.loadImage("settings_icon", "ui");
|
||||||
|
|
||||||
this.loadImage("default_bg", "arenas");
|
this.loadImage("default_bg", "arenas");
|
||||||
// Load arena images
|
// Load arena images
|
||||||
|
@ -244,7 +248,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 +274,7 @@ export class LoadingScene extends SceneBase {
|
||||||
this.loadImage("gacha_knob", "egg");
|
this.loadImage("gacha_knob", "egg");
|
||||||
|
|
||||||
this.loadImage("egg_list_bg", "ui");
|
this.loadImage("egg_list_bg", "ui");
|
||||||
|
this.loadImage("egg_summary_bg", "ui");
|
||||||
|
|
||||||
this.loadImage("end_m", "cg");
|
this.loadImage("end_m", "cg");
|
||||||
this.loadImage("end_f", "cg");
|
this.loadImage("end_f", "cg");
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,5 +36,6 @@
|
||||||
"matBlock": "Tatami-Schild",
|
"matBlock": "Tatami-Schild",
|
||||||
"craftyShield": "Trickschutz",
|
"craftyShield": "Trickschutz",
|
||||||
"tailwind": "Rückenwind",
|
"tailwind": "Rückenwind",
|
||||||
"happyHour": "Goldene Zeiten"
|
"happyHour": "Goldene Zeiten",
|
||||||
}
|
"safeguard": "Bodyguard"
|
||||||
|
}
|
||||||
|
|
|
@ -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?"
|
||||||
}
|
}
|
|
@ -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",
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
|
@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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!",
|
||||||
|
|
|
@ -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!"
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,5 +10,5 @@
|
||||||
"eternamaxChange": "{{preName}} hat sich zu {{pokemonName}} unendynamaximiert!",
|
"eternamaxChange": "{{preName}} hat sich zu {{pokemonName}} unendynamaximiert!",
|
||||||
"revertChange": "{{pokemonName}} hat seine ursprüngliche Form zurückerlangt!",
|
"revertChange": "{{pokemonName}} hat seine ursprüngliche Form zurückerlangt!",
|
||||||
"formChange": "{{preName}} hat seine Form geändert!",
|
"formChange": "{{preName}} hat seine Form geändert!",
|
||||||
"disguiseChange": "Its disguise served it as a decoy!"
|
"disguiseChange": "Sein Kostüm hat die Attacke absorbiert!"
|
||||||
}
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
{
|
{
|
||||||
"Stat": {
|
"Stat": {
|
||||||
"HP": "KP",
|
"HP": "KP",
|
||||||
"HPStat": "KP",
|
|
||||||
"HPshortened": "KP",
|
"HPshortened": "KP",
|
||||||
"ATK": "Angriff",
|
"ATK": "Angriff",
|
||||||
"ATKshortened": "Ang",
|
"ATKshortened": "Ang",
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -1,268 +0,0 @@
|
||||||
{
|
|
||||||
"Achievements": {
|
|
||||||
"name": "Achievements"
|
|
||||||
},
|
|
||||||
"Locked": {
|
|
||||||
"name": "Locked"
|
|
||||||
},
|
|
||||||
"MoneyAchv": {
|
|
||||||
"description": "Accumulate a total of ₽{{moneyAmount}}"
|
|
||||||
},
|
|
||||||
"10K_MONEY": {
|
|
||||||
"name": "Money Haver"
|
|
||||||
},
|
|
||||||
"100K_MONEY": {
|
|
||||||
"name": "Rich"
|
|
||||||
},
|
|
||||||
"1M_MONEY": {
|
|
||||||
"name": "Millionaire"
|
|
||||||
},
|
|
||||||
"10M_MONEY": {
|
|
||||||
"name": "One Percenter"
|
|
||||||
},
|
|
||||||
"DamageAchv": {
|
|
||||||
"description": "Inflict {{damageAmount}} damage in one hit"
|
|
||||||
},
|
|
||||||
"250_DMG": {
|
|
||||||
"name": "Hard Hitter"
|
|
||||||
},
|
|
||||||
"1000_DMG": {
|
|
||||||
"name": "Harder Hitter"
|
|
||||||
},
|
|
||||||
"2500_DMG": {
|
|
||||||
"name": "That's a Lotta Damage!"
|
|
||||||
},
|
|
||||||
"10000_DMG": {
|
|
||||||
"name": "One Punch Man"
|
|
||||||
},
|
|
||||||
"HealAchv": {
|
|
||||||
"description": "Heal {{healAmount}} {{HP}} at once with a move, ability, or held item"
|
|
||||||
},
|
|
||||||
"250_HEAL": {
|
|
||||||
"name": "Novice Healer"
|
|
||||||
},
|
|
||||||
"1000_HEAL": {
|
|
||||||
"name": "Big Healer"
|
|
||||||
},
|
|
||||||
"2500_HEAL": {
|
|
||||||
"name": "Cleric"
|
|
||||||
},
|
|
||||||
"10000_HEAL": {
|
|
||||||
"name": "Recovery Master"
|
|
||||||
},
|
|
||||||
"LevelAchv": {
|
|
||||||
"description": "Level up a Pokémon to Lv{{level}}"
|
|
||||||
},
|
|
||||||
"LV_100": {
|
|
||||||
"name": "But Wait, There's More!"
|
|
||||||
},
|
|
||||||
"LV_250": {
|
|
||||||
"name": "Elite"
|
|
||||||
},
|
|
||||||
"LV_1000": {
|
|
||||||
"name": "To Go Even Further Beyond"
|
|
||||||
},
|
|
||||||
"RibbonAchv": {
|
|
||||||
"description": "Accumulate a total of {{ribbonAmount}} Ribbons"
|
|
||||||
},
|
|
||||||
"10_RIBBONS": {
|
|
||||||
"name": "Pokémon League Champion"
|
|
||||||
},
|
|
||||||
"25_RIBBONS": {
|
|
||||||
"name": "Great League Champion"
|
|
||||||
},
|
|
||||||
"50_RIBBONS": {
|
|
||||||
"name": "Ultra League Champion"
|
|
||||||
},
|
|
||||||
"75_RIBBONS": {
|
|
||||||
"name": "Rogue League Champion"
|
|
||||||
},
|
|
||||||
"100_RIBBONS": {
|
|
||||||
"name": "Master League Champion"
|
|
||||||
},
|
|
||||||
"TRANSFER_MAX_BATTLE_STAT": {
|
|
||||||
"name": "Teamwork",
|
|
||||||
"description": "Baton pass to another party member with at least one stat maxed out"
|
|
||||||
},
|
|
||||||
"MAX_FRIENDSHIP": {
|
|
||||||
"name": "Friendmaxxing",
|
|
||||||
"description": "Reach max friendship on a Pokémon"
|
|
||||||
},
|
|
||||||
"MEGA_EVOLVE": {
|
|
||||||
"name": "Megamorph",
|
|
||||||
"description": "Mega evolve a Pokémon"
|
|
||||||
},
|
|
||||||
"GIGANTAMAX": {
|
|
||||||
"name": "Absolute Unit",
|
|
||||||
"description": "Gigantamax a Pokémon"
|
|
||||||
},
|
|
||||||
"TERASTALLIZE": {
|
|
||||||
"name": "STAB Enthusiast",
|
|
||||||
"description": "Terastallize a Pokémon"
|
|
||||||
},
|
|
||||||
"STELLAR_TERASTALLIZE": {
|
|
||||||
"name": "The Hidden Type",
|
|
||||||
"description": "Stellar Terastallize a Pokémon"
|
|
||||||
},
|
|
||||||
"SPLICE": {
|
|
||||||
"name": "Infinite Fusion",
|
|
||||||
"description": "Splice two Pokémon together with DNA Splicers"
|
|
||||||
},
|
|
||||||
"MINI_BLACK_HOLE": {
|
|
||||||
"name": "A Hole Lot of Items",
|
|
||||||
"description": "Acquire a Mini Black Hole"
|
|
||||||
},
|
|
||||||
"CATCH_MYTHICAL": {
|
|
||||||
"name": "Mythical",
|
|
||||||
"description": "Catch a mythical Pokémon"
|
|
||||||
},
|
|
||||||
"CATCH_SUB_LEGENDARY": {
|
|
||||||
"name": "(Sub-)Legendary",
|
|
||||||
"description": "Catch a sub-legendary Pokémon"
|
|
||||||
},
|
|
||||||
"CATCH_LEGENDARY": {
|
|
||||||
"name": "Legendary",
|
|
||||||
"description": "Catch a legendary Pokémon"
|
|
||||||
},
|
|
||||||
"SEE_SHINY": {
|
|
||||||
"name": "Shiny",
|
|
||||||
"description": "Find a shiny Pokémon in the wild"
|
|
||||||
},
|
|
||||||
"SHINY_PARTY": {
|
|
||||||
"name": "That's Dedication",
|
|
||||||
"description": "Have a full party of shiny Pokémon"
|
|
||||||
},
|
|
||||||
"HATCH_MYTHICAL": {
|
|
||||||
"name": "Mythical Egg",
|
|
||||||
"description": "Hatch a mythical Pokémon from an egg"
|
|
||||||
},
|
|
||||||
"HATCH_SUB_LEGENDARY": {
|
|
||||||
"name": "Sub-Legendary Egg",
|
|
||||||
"description": "Hatch a sub-legendary Pokémon from an egg"
|
|
||||||
},
|
|
||||||
"HATCH_LEGENDARY": {
|
|
||||||
"name": "Legendary Egg",
|
|
||||||
"description": "Hatch a legendary Pokémon from an egg"
|
|
||||||
},
|
|
||||||
"HATCH_SHINY": {
|
|
||||||
"name": "Shiny Egg",
|
|
||||||
"description": "Hatch a shiny Pokémon from an egg"
|
|
||||||
},
|
|
||||||
"HIDDEN_ABILITY": {
|
|
||||||
"name": "Hidden Potential",
|
|
||||||
"description": "Catch a Pokémon with a hidden ability"
|
|
||||||
},
|
|
||||||
"PERFECT_IVS": {
|
|
||||||
"name": "Certificate of Authenticity",
|
|
||||||
"description": "Get perfect IVs on a Pokémon"
|
|
||||||
},
|
|
||||||
"CLASSIC_VICTORY": {
|
|
||||||
"name": "Undefeated",
|
|
||||||
"description": "Beat the game in classic mode"
|
|
||||||
},
|
|
||||||
"UNEVOLVED_CLASSIC_VICTORY": {
|
|
||||||
"name": "Bring Your Child To Work Day",
|
|
||||||
"description": "Beat the game in Classic Mode with at least one unevolved party member."
|
|
||||||
},
|
|
||||||
"MONO_GEN_ONE": {
|
|
||||||
"name": "The Original Rival",
|
|
||||||
"description": "Complete the generation one only challenge."
|
|
||||||
},
|
|
||||||
"MONO_GEN_TWO": {
|
|
||||||
"name": "Generation 1.5",
|
|
||||||
"description": "Complete the generation two only challenge."
|
|
||||||
},
|
|
||||||
"MONO_GEN_THREE": {
|
|
||||||
"name": "Too much water?",
|
|
||||||
"description": "Complete the generation three only challenge."
|
|
||||||
},
|
|
||||||
"MONO_GEN_FOUR": {
|
|
||||||
"name": "Is she really the hardest?",
|
|
||||||
"description": "Complete the generation four only challenge."
|
|
||||||
},
|
|
||||||
"MONO_GEN_FIVE": {
|
|
||||||
"name": "All Original",
|
|
||||||
"description": "Complete the generation five only challenge."
|
|
||||||
},
|
|
||||||
"MONO_GEN_SIX": {
|
|
||||||
"name": "Almost Royalty",
|
|
||||||
"description": "Complete the generation six only challenge."
|
|
||||||
},
|
|
||||||
"MONO_GEN_SEVEN": {
|
|
||||||
"name": "Only Technically",
|
|
||||||
"description": "Complete the generation seven only challenge."
|
|
||||||
},
|
|
||||||
"MONO_GEN_EIGHT": {
|
|
||||||
"name": "A Champion Time!",
|
|
||||||
"description": "Complete the generation eight only challenge."
|
|
||||||
},
|
|
||||||
"MONO_GEN_NINE": {
|
|
||||||
"name": "She was going easy on you",
|
|
||||||
"description": "Complete the generation nine only challenge."
|
|
||||||
},
|
|
||||||
"MonoType": {
|
|
||||||
"description": "Complete the {{type}} monotype challenge."
|
|
||||||
},
|
|
||||||
"MONO_NORMAL": {
|
|
||||||
"name": "Extra Ordinary"
|
|
||||||
},
|
|
||||||
"MONO_FIGHTING": {
|
|
||||||
"name": "I Know Kung Fu"
|
|
||||||
},
|
|
||||||
"MONO_FLYING": {
|
|
||||||
"name": "Angry Birds"
|
|
||||||
},
|
|
||||||
"MONO_POISON": {
|
|
||||||
"name": "Kanto's Favourite"
|
|
||||||
},
|
|
||||||
"MONO_GROUND": {
|
|
||||||
"name": "Forecast: Earthquakes"
|
|
||||||
},
|
|
||||||
"MONO_ROCK": {
|
|
||||||
"name": "Brock Hard"
|
|
||||||
},
|
|
||||||
"MONO_BUG": {
|
|
||||||
"name": "You Like Jazz?"
|
|
||||||
},
|
|
||||||
"MONO_GHOST": {
|
|
||||||
"name": "Who You Gonna Call?"
|
|
||||||
},
|
|
||||||
"MONO_STEEL": {
|
|
||||||
"name": "Iron Giant"
|
|
||||||
},
|
|
||||||
"MONO_FIRE": {
|
|
||||||
"name": "I Cast Fireball!"
|
|
||||||
},
|
|
||||||
"MONO_WATER": {
|
|
||||||
"name": "When It Rains, It Pours"
|
|
||||||
},
|
|
||||||
"MONO_GRASS": {
|
|
||||||
"name": "Can't Touch This"
|
|
||||||
},
|
|
||||||
"MONO_ELECTRIC": {
|
|
||||||
"name": "Aim For The Horn!"
|
|
||||||
},
|
|
||||||
"MONO_PSYCHIC": {
|
|
||||||
"name": "Big Brain Energy"
|
|
||||||
},
|
|
||||||
"MONO_ICE": {
|
|
||||||
"name": "Walking On Thin Ice"
|
|
||||||
},
|
|
||||||
"MONO_DRAGON": {
|
|
||||||
"name": "Pseudo-Legend Club"
|
|
||||||
},
|
|
||||||
"MONO_DARK": {
|
|
||||||
"name": "It's Just A Phase"
|
|
||||||
},
|
|
||||||
"MONO_FAIRY": {
|
|
||||||
"name": "Hey! Listen!"
|
|
||||||
},
|
|
||||||
"FRESH_START": {
|
|
||||||
"name": "First Try!",
|
|
||||||
"description": "Complete the Fresh Start challenge."
|
|
||||||
},
|
|
||||||
"INVERSE_BATTLE": {
|
|
||||||
"name": "Mirror rorriM",
|
|
||||||
"description": "Complete the Inverse Battle challenge.\n.egnellahc elttaB esrevnI eht etelpmoC"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,5 +39,6 @@
|
||||||
"matBlock": "Mat Block",
|
"matBlock": "Mat Block",
|
||||||
"craftyShield": "Crafty Shield",
|
"craftyShield": "Crafty Shield",
|
||||||
"tailwind": "Tailwind",
|
"tailwind": "Tailwind",
|
||||||
"happyHour": "Happy Hour"
|
"happyHour": "Happy Hour",
|
||||||
}
|
"safeguard": "Safeguard"
|
||||||
|
}
|
|
@ -47,5 +47,11 @@
|
||||||
"tailwindOnRemovePlayer": "Your team's Tailwind petered out!",
|
"tailwindOnRemovePlayer": "Your team's Tailwind petered out!",
|
||||||
"tailwindOnRemoveEnemy": "The opposing team's Tailwind petered out!",
|
"tailwindOnRemoveEnemy": "The opposing team's Tailwind petered out!",
|
||||||
"happyHourOnAdd": "Everyone is caught up in the happy atmosphere!",
|
"happyHourOnAdd": "Everyone is caught up in the happy atmosphere!",
|
||||||
"happyHourOnRemove": "The atmosphere returned to normal."
|
"happyHourOnRemove": "The atmosphere returned to normal.",
|
||||||
|
"safeguardOnAdd": "The whole field is cloaked in a mystical veil!",
|
||||||
|
"safeguardOnAddPlayer": "Your team cloaked itself in a mystical veil!",
|
||||||
|
"safeguardOnAddEnemy": "The opposing team cloaked itself in a mystical veil!",
|
||||||
|
"safeguardOnRemove": "The field is no longer protected by Safeguard!",
|
||||||
|
"safeguardOnRemovePlayer": "Your team is no longer protected by Safeguard!",
|
||||||
|
"safeguardOnRemoveEnemy": "The opposing team is no longer protected by Safeguard!"
|
||||||
}
|
}
|
|
@ -44,6 +44,7 @@
|
||||||
"moveNotImplemented": "{{moveName}} is not yet implemented and cannot be selected.",
|
"moveNotImplemented": "{{moveName}} is not yet implemented and cannot be selected.",
|
||||||
"moveNoPP": "There's no PP left for\nthis move!",
|
"moveNoPP": "There's no PP left for\nthis move!",
|
||||||
"moveDisabled": "{{moveName}} is disabled!",
|
"moveDisabled": "{{moveName}} is disabled!",
|
||||||
|
"disableInterruptedMove": "{{pokemonNameWithAffix}}'s {{moveName}}\nis disabled!",
|
||||||
"noPokeballForce": "An unseen force\nprevents using Poké Balls.",
|
"noPokeballForce": "An unseen force\nprevents using Poké Balls.",
|
||||||
"noPokeballTrainer": "You can't catch\nanother trainer's Pokémon!",
|
"noPokeballTrainer": "You can't catch\nanother trainer's Pokémon!",
|
||||||
"noPokeballMulti": "You can only throw a Poké Ball\nwhen there is one Pokémon remaining!",
|
"noPokeballMulti": "You can only throw a Poké Ball\nwhen there is one Pokémon remaining!",
|
||||||
|
@ -61,6 +62,7 @@
|
||||||
"skipItemQuestion": "Are you sure you want to skip taking an item?",
|
"skipItemQuestion": "Are you sure you want to skip taking an item?",
|
||||||
"itemStackFull": "The stack for {{fullItemName}} is full.\nYou will receive {{itemName}} instead.",
|
"itemStackFull": "The stack for {{fullItemName}} is full.\nYou will receive {{itemName}} instead.",
|
||||||
"eggHatching": "Oh?",
|
"eggHatching": "Oh?",
|
||||||
|
"eggSkipPrompt": "Skip to egg summary?",
|
||||||
"ivScannerUseQuestion": "Use IV Scanner on {{pokemonName}}?",
|
"ivScannerUseQuestion": "Use IV Scanner on {{pokemonName}}?",
|
||||||
"wildPokemonWithAffix": "Wild {{pokemonName}}",
|
"wildPokemonWithAffix": "Wild {{pokemonName}}",
|
||||||
"foePokemonWithAffix": "Foe {{pokemonName}}",
|
"foePokemonWithAffix": "Foe {{pokemonName}}",
|
||||||
|
|
|
@ -67,5 +67,7 @@
|
||||||
"saltCuredLapse": "{{pokemonNameWithAffix}} is hurt by {{moveName}}!",
|
"saltCuredLapse": "{{pokemonNameWithAffix}} is hurt by {{moveName}}!",
|
||||||
"cursedOnAdd": "{{pokemonNameWithAffix}} cut its own HP and put a curse on the {{pokemonName}}!",
|
"cursedOnAdd": "{{pokemonNameWithAffix}} cut its own HP and put a curse on the {{pokemonName}}!",
|
||||||
"cursedLapse": "{{pokemonNameWithAffix}} is afflicted by the Curse!",
|
"cursedLapse": "{{pokemonNameWithAffix}} is afflicted by the Curse!",
|
||||||
"stockpilingOnAdd": "{{pokemonNameWithAffix}} stockpiled {{stockpiledCount}}!"
|
"stockpilingOnAdd": "{{pokemonNameWithAffix}} stockpiled {{stockpiledCount}}!",
|
||||||
}
|
"disabledOnAdd": "{{pokemonNameWithAffix}}'s {{moveName}}\nwas disabled!",
|
||||||
|
"disabledLapse": "{{pokemonNameWithAffix}}'s {{moveName}}\nis no longer disabled."
|
||||||
|
}
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
||||||
|
|
|
@ -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..."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -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!"
|
||||||
}
|
}
|
|
@ -51,5 +51,7 @@
|
||||||
"renamePokemon": "Rename Pokémon",
|
"renamePokemon": "Rename Pokémon",
|
||||||
"rename": "Rename",
|
"rename": "Rename",
|
||||||
"nickname": "Nickname",
|
"nickname": "Nickname",
|
||||||
"errorServerDown": "Oops! There was an issue contacting the server.\n\nYou may leave this window open,\nthe game will automatically reconnect."
|
"errorServerDown": "Oops! There was an issue contacting the server.\n\nYou may leave this window open,\nthe game will automatically reconnect.",
|
||||||
|
"noSaves": "You don't have any save files on record!",
|
||||||
|
"tooManySaves": "You have too many save files on record!"
|
||||||
}
|
}
|
|
@ -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",
|
||||||
|
|
|
@ -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}}!",
|
||||||
|
|
|
@ -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!",
|
||||||
|
@ -61,5 +65,6 @@
|
||||||
"suppressAbilities": "{{pokemonName}}'s ability\nwas suppressed!",
|
"suppressAbilities": "{{pokemonName}}'s ability\nwas suppressed!",
|
||||||
"revivalBlessing": "{{pokemonName}} was revived!",
|
"revivalBlessing": "{{pokemonName}} was revived!",
|
||||||
"swapArenaTags": "{{pokemonName}} swapped the battle effects affecting each side of the field!",
|
"swapArenaTags": "{{pokemonName}} swapped the battle effects affecting each side of the field!",
|
||||||
"exposedMove": "{{pokemonName}} identified\n{{targetPokemonName}}!"
|
"exposedMove": "{{pokemonName}} identified\n{{targetPokemonName}}!",
|
||||||
}
|
"safeguard": "{{targetName}} is protected by Safeguard!"
|
||||||
|
}
|
|
@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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",
|
||||||
|
@ -36,5 +36,6 @@
|
||||||
"matBlock": "Escudo Tatami",
|
"matBlock": "Escudo Tatami",
|
||||||
"craftyShield": "Truco Defensa",
|
"craftyShield": "Truco Defensa",
|
||||||
"tailwind": "Viento Afín",
|
"tailwind": "Viento Afín",
|
||||||
"happyHour": "Paga Extra"
|
"happyHour": "Paga Extra",
|
||||||
}
|
"safeguard": "Velo Sagrado"
|
||||||
|
}
|
||||||
|
|
|
@ -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!",
|
||||||
|
|
|
@ -1 +1,71 @@
|
||||||
{}
|
{
|
||||||
|
"trappedDesc": "trampa",
|
||||||
|
"flinchedDesc": "retroceso",
|
||||||
|
"confusedDesc": "confusión",
|
||||||
|
"infatuatedDesc": "enamoramiento",
|
||||||
|
"seedDesc": "drenado",
|
||||||
|
"nightmareDesc": "pesadillas",
|
||||||
|
"ingrainDesc": "raíces",
|
||||||
|
"drowsyDesc": "sueño",
|
||||||
|
"rechargingLapse": "¡{{pokemonNameWithAffix}} necesita\nrecuperarse de su ataque!",
|
||||||
|
"trappedOnAdd": "¡{{pokemonNameWithAffix}} no puede escapar!",
|
||||||
|
"trappedOnRemove": "¡{{pokemonNameWithAffix}} se ha\nliberado de {{moveName}}!",
|
||||||
|
"flinchedLapse": "¡{{pokemonNameWithAffix}} se amedrentó!",
|
||||||
|
"confusedOnAdd": "¡{{pokemonNameWithAffix}} se encuentra confuso!",
|
||||||
|
"confusedOnRemove": "¡{{pokemonNameWithAffix}} ya no está confuso!",
|
||||||
|
"confusedOnOverlap": "¡{{pokemonNameWithAffix}} ya está confuso!",
|
||||||
|
"confusedLapse": "¡{{pokemonNameWithAffix}} está confuso!",
|
||||||
|
"confusedLapseHurtItself": "¡Está tan confuso que se ha herido a sí mismo!",
|
||||||
|
"destinyBondLapseIsBoss": "Mismo Destino no afecta a {{pokemonNameWithAffix}}.",
|
||||||
|
"destinyBondLapse": "¡{{pokemonNameWithAffix2}} ha sufrido\nel mismo destino que {{pokemonNameWithAffix}}!",
|
||||||
|
"infatuatedOnAdd": "¡{{pokemonNameWithAffix}} se ha enamorado\nde {{sourcePokemonName}}!",
|
||||||
|
"infatuatedOnOverlap": "¡{{pokemonNameWithAffix}} ya está enamorado!",
|
||||||
|
"infatuatedLapse": "¡{{pokemonNameWithAffix}} se ha enamorado\ndebido a {{sourcePokemonName}}!",
|
||||||
|
"infatuatedLapseImmobilize": "¡El enamoramiento impide que\n{{pokemonNameWithAffix}} reaccione!",
|
||||||
|
"infatuatedOnRemove": "{{pokemonNameWithAffix}} ya no está enamorado.",
|
||||||
|
"seededOnAdd": "¡{{pokemonNameWithAffix}} ha sido infectado!",
|
||||||
|
"seededLapse": "¡Las drenadoras han restado salud a {{pokemonNameWithAffix}}!",
|
||||||
|
"seededLapseShed": "¡{{pokemonNameWithAffix}} ha absorbido el lodo líquido!",
|
||||||
|
"nightmareOnAdd": "¡{{pokemonNameWithAffix}} se ha sumido en una pesadilla!",
|
||||||
|
"nightmareOnOverlap": "¡{{pokemonNameWithAffix}} ya está teniendo pesadillas!",
|
||||||
|
"nightmareLapse": "¡{{pokemonNameWithAffix}} sufre pesadillas!",
|
||||||
|
"encoreOnAdd": "¡{{pokemonNameWithAffix}} sufre los efectos de Otra Vez!",
|
||||||
|
"encoreOnRemove": "¡{{pokemonNameWithAffix}} ya no sufre los efectos de Otra Vez!",
|
||||||
|
"helpingHandOnAdd": "¡{{pokemonNameWithAffix}} se prepara\npara ayudar a {{pokemonName}}!",
|
||||||
|
"ingrainLapse": "¡{{pokemonNameWithAffix}} ha absorbido\nnutrientes a través de sus raíces!",
|
||||||
|
"ingrainOnTrap": "¡{{pokemonNameWithAffix}} ha echado raíces!",
|
||||||
|
"aquaRingOnAdd": "¡{{pokemonNameWithAffix}} se ha rodeado de un manto de agua!",
|
||||||
|
"aquaRingLapse": "¡{{pokemonName}} restauró sus PS con {{moveName}}!",
|
||||||
|
"drowsyOnAdd": "¡{{pokemonNameWithAffix}} empieza a tener sueño!",
|
||||||
|
"damagingTrapLapse": "¡{{moveName}} hiere a {{pokemonNameWithAffix}}!",
|
||||||
|
"bindOnTrap": "¡{{moveName}} de {{sourcePokemonName}} oprime a {{pokemonNameWithAffix}}!",
|
||||||
|
"wrapOnTrap": "¡{{sourcePokemonName}} ha atrapado a {{pokemonNameWithAffix}} con una constricción!",
|
||||||
|
"vortexOnTrap": "¡{{pokemonNameWithAffix}} no puede salir del torbellino!",
|
||||||
|
"clampOnTrap": "¡{{sourcePokemonNameWithAffix}} ha atenazado a \n{{pokemonName}}!",
|
||||||
|
"sandTombOnTrap": "¡{{pokemonNameWithAffix}} ha sido atrapado por {{moveName}}!",
|
||||||
|
"magmaStormOnTrap": "¡La lluvia ígnea cae sobre {{pokemonNameWithAffix}}!",
|
||||||
|
"snapTrapOnTrap": "¡{{pokemonNameWithAffix}} cayó en un cepo!",
|
||||||
|
"thunderCageOnTrap": "¡{{sourcePokemonNameWithAffix}} ha enjaulado a {{pokemonNameWithAffix}}!",
|
||||||
|
"infestationOnTrap": "¡{{pokemonNameWithAffix}} es presa del acoso de {{sourcePokemonNameWithAffix}}!",
|
||||||
|
"protectedOnAdd": "{{pokemonNameWithAffix}}\nse está protegiendo.",
|
||||||
|
"protectedLapse": "¡{{pokemonNameWithAffix}}\nse ha protegido!",
|
||||||
|
"enduringOnAdd": "{{pokemonNameWithAffix}} se prepara para resistir los ataques...",
|
||||||
|
"enduringLapse": "¡{{pokemonNameWithAffix}} ha encajado el golpe!",
|
||||||
|
"sturdyLapse": "¡{{pokemonNameWithAffix}} ha encajado el golpe!",
|
||||||
|
"perishSongLapse": "La cuenta atrás de Canto Mortal de\n{{pokemonNameWithAffix}} ha bajado a {{turnCount}}.",
|
||||||
|
"centerOfAttentionOnAdd": "¡{{pokemonNameWithAffix}} es el centro de atención!",
|
||||||
|
"truantLapse": "{{pokemonNameWithAffix}} está holgazaneando...",
|
||||||
|
"slowStartOnAdd": "¡{{pokemonNameWithAffix}} no está dando todo de sí!",
|
||||||
|
"slowStartOnRemove": "¡{{pokemonNameWithAffix}} ya puede darlo todo!",
|
||||||
|
"highestStatBoostOnAdd": "¡{{pokemonNameWithAffix}} ha reforzado su {{statName}}!",
|
||||||
|
"highestStatBoostOnRemove": "¡Los efectos de {{abilityName}}\nde {{pokemonNameWithAffix}} han desaparecido!",
|
||||||
|
"magnetRisenOnAdd": "¡{{pokemonNameWithAffix}} levita gracias a un campo electromagnético!",
|
||||||
|
"magnetRisenOnRemove": "¡El campo electromagnético de {{pokemonNameWithAffix}} se ha disipado!",
|
||||||
|
"critBoostOnAdd": "¡{{pokemonNameWithAffix}} se está preparando para luchar!",
|
||||||
|
"critBoostOnRemove": "{{pokemonNameWithAffix}} se ha relajado.",
|
||||||
|
"saltCuredOnAdd": "¡{{pokemonNameWithAffix}} está en salazón!",
|
||||||
|
"saltCuredLapse": "¡{{moveName}} ha herido a {{pokemonNameWithAffix}}!",
|
||||||
|
"cursedOnAdd": "¡{{pokemonNameWithAffix}} sacrifica algunos PS y maldice a {{pokemonName}}!",
|
||||||
|
"cursedLapse": "¡{{pokemonNameWithAffix}} es víctima de una maldición!",
|
||||||
|
"stockpilingOnAdd": "¡{{pokemonNameWithAffix}} ha reservado energía por {{stockpiledCount}}ª vez!"
|
||||||
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
{
|
{
|
||||||
"classic": "Clásica",
|
"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"
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,14 +14,14 @@
|
||||||
"register": "Registrarse",
|
"register": "Registrarse",
|
||||||
"emptyUsername": "El usuario no puede estar vacío",
|
"emptyUsername": "El usuario no puede estar vacío",
|
||||||
"invalidLoginUsername": "El usuario no es válido",
|
"invalidLoginUsername": "El usuario no es válido",
|
||||||
"invalidRegisterUsername": "El usuario solo puede contener letras, números y guiones bajos",
|
"invalidRegisterUsername": "El usuario solo puede contener letras, números y guiones bajos.",
|
||||||
"invalidLoginPassword": "La contraseña no es válida",
|
"invalidLoginPassword": "La contraseña no es válida",
|
||||||
"invalidRegisterPassword": "La contraseña debe tener 6 o más caracteres.",
|
"invalidRegisterPassword": "La contraseña debe tener 6 o más caracteres.",
|
||||||
"usernameAlreadyUsed": "El usuario ya está en uso",
|
"usernameAlreadyUsed": "El usuario ya está en uso",
|
||||||
"accountNonExistent": "El usuario no existe",
|
"accountNonExistent": "El usuario no existe",
|
||||||
"unmatchingPassword": "La contraseña no coincide",
|
"unmatchingPassword": "La contraseña no coincide",
|
||||||
"passwordNotMatchingConfirmPassword": "Las contraseñas deben coincidir",
|
"passwordNotMatchingConfirmPassword": "Las contraseñas deben coincidir",
|
||||||
"confirmPassword": "Confirmar Contra.",
|
"confirmPassword": "Confirmar contraseña",
|
||||||
"registrationAgeWarning": "Al registrarte, confirmas tener 13 o más años de edad.",
|
"registrationAgeWarning": "Al registrarte, confirmas tener 13 o más años de edad.",
|
||||||
"backToLogin": "Volver al Login",
|
"backToLogin": "Volver al Login",
|
||||||
"failedToLoadSaveData": "No se han podido cargar los datos guardados. Por favor, recarga la página.\nSi el fallo continúa, por favor comprueba #announcements en nuestro Discord.",
|
"failedToLoadSaveData": "No se han podido cargar los datos guardados. Por favor, recarga la página.\nSi el fallo continúa, por favor comprueba #announcements en nuestro Discord.",
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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!"
|
||||||
}
|
}
|
||||||
|
|
|
@ -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}}!"
|
||||||
}
|
}
|
||||||
|
|
|
@ -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!"
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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."
|
||||||
},
|
},
|
||||||
|
|
|
@ -36,5 +36,6 @@
|
||||||
"matBlock": "Tatamigaeshi",
|
"matBlock": "Tatamigaeshi",
|
||||||
"craftyShield": "Vigilance",
|
"craftyShield": "Vigilance",
|
||||||
"tailwind": "Vent Arrière",
|
"tailwind": "Vent Arrière",
|
||||||
"happyHour": "Étrennes"
|
"happyHour": "Étrennes",
|
||||||
}
|
"safeguard": "Rune Protect"
|
||||||
|
}
|
||||||
|
|
|
@ -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 ?"
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"ending": "@c{smile}Oh ? T’as gagné ?@d{96} @c{smile_eclosed}J’aurais dû le savoir.\nMais de voilà de retour.\n$@c{smile}C’est terminé.@d{64} T’as brisé ce cycle infernal.\n$@c{serious_smile_fists}T’as aussi accompli ton rêve non ?\nTu n’as pas connu la moindre défaite.\n$@c{neutral}Je suis le seul à me souvenir de ce que t’as 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, j’en ai un peu marre de ce endroit, pas toi ? Rentrons à la maison.\n$@c{serious_smile_fists}On se fera un p’tit combat une fois rentrés ?\nSi t’es d’accord.",
|
"ending": "@c{shock}T’es revenu ?@d{32} Ça veut dire…@d{96} que t’as gagné ?!\n@c{smile_ehalf}J’aurais dû m’en douter.\n$@c{smile_eclosed}Bien sûr… J’ai toujours eu ce sentiment.\n@c{smile}C’est fini maintenant hein ? T’as brisé ce cycle.\n$@c{smile_ehalf}T’as aussi accompli ton rêve non ?\nTu n’as pas connu la moindre défaite.\n$Je serai la seule à me souvenir de ce que t’as fait.\n@c{angry_mopen}Je tâcherai de ne pas oublier !\n$@c{smile_wave_wink}J’déconne !@d{64} @c{smile}Jamais j’oublierai.@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 p’tit combat, comme au bon vieux temps ?",
|
||||||
"ending_female": "@c{shock}T’es revenu ?@d{32} Ça veut dire…@d{96} que t’as gagné ?!\n@c{smile_ehalf}J’aurais dû le savoir.\n$@c{smile_eclosed}Bien sûr… J’ai toujours eu ce sentiment.\n@c{smile}C’est fini maitenant hein ? T’as brisé ce cycle.\n$@c{smile_ehalf}T’as aussi accompli ton rêve non ?\nTu n’as pas connu la moindre défaite.\n$Je serai la seule à me souvenir de ce que t’as fait.\n@c{angry_mopen}Je tâcherai de ne pas oublier !\n$@c{smile_wave_wink}J’déconne !@d{64} @c{smile}Jamais j’oublierai.@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 p’tit combat, comme au bon vieux temps ?",
|
"ending_female": "@c{smile}Oh ? T’as gagné ?@d{96} @c{smile_eclosed}J’aurais dû m’en douter.\nMais te voilà enfin de retour.\n$@c{smile}C’est terminé.@d{64} T’as brisé ce cycle infernal.\n$@c{serious_smile_fists}T’as aussi accompli ton rêve non ?\nTu n’as pas connu la moindre défaite.\n$@c{neutral}Je suis le seul à me souvenir de ce que t’as 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, j’en ai un peu marre de ce endroit, pas toi ? Rentrons à la maison.\n$@c{serious_smile_fists}On se fera un p’tit combat une fois rentrés ?\nSi t’es d’accord.",
|
||||||
"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"
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
"6": "Allez, c’est parti !",
|
"6": "Allez, c’est parti !",
|
||||||
"7": "Attention, me voilà !\nTu vas voir comment j’suis fort !",
|
"7": "Attention, me voilà !\nTu vas voir comment j’suis 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 d’avoir perdu face à un gamin.",
|
"10": "Baisse pas ta garde si tu veux pas pleurer d’avoir perdu face à un gamin.",
|
||||||
"11": "J’ai tout donné pour élever mes Pokémon. Attention à toi si tu leur fait du mal !",
|
"11": "J’ai tout donné pour élever mes Pokémon. Attention à toi si tu leur fait du mal !",
|
||||||
"12": "Incroyable que t’y sois parvenu ! Mais la suite va pas être une partie de plaisir.",
|
"12": "Incroyable que t’y sois parvenu ! Mais la suite va pas être une partie de plaisir.",
|
||||||
|
@ -68,7 +68,7 @@
|
||||||
"3": "Hum, t’es pas trop laxiste avec tes Pokémon ?\nTrop les chouchouter n’est pas bon."
|
"3": "Hum, t’es pas trop laxiste avec tes Pokémon ?\nTrop les chouchouter n’est 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": "J’espère que t’es prêt à te prendre une raclée de l’espace !",
|
"5": "J’espère que t’es prêt à te prendre une raclée de l’espace !",
|
||||||
"5_female": "J’espère que t’es prête à te prendre une raclée de l’espace !"
|
"5_female": "J’espère que t’es prête à te prendre une raclée de l’espace !"
|
||||||
|
@ -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 m’occuperai de toi personnellement !",
|
"3": "Si tu te mets en travers de la Team Plasma, je m’occuperai 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": "J’appelle pas ça perdre, j’appelle ça échouer avec panache !"
|
"5": "J’appelle pas ça perdre, j’appelle ça échouer avec panache !"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"aether_grunt": {
|
||||||
|
"encounter": {
|
||||||
|
"1": "Je vais te mettre ta raclée !",
|
||||||
|
"2": "J’en ai rien à faire que tu sois une gosse. Tu vas tutoyer les étoiles si tu nous menaces !",
|
||||||
|
"2_female": "J’en ai rien à faire que tu sois une gosse. Tu vas tutoyer les étoiles si tu nous menaces !",
|
||||||
|
"3": "J’ai pour ordre de ne laisser passer aucun Dresseur, peu importe qui c’est !",
|
||||||
|
"4": "Je vais te montrer le pouvoir du Paradis Æther !",
|
||||||
|
"5": "Maintenant que t’es au courant de ce qu’il se passe au cœur du Paradis Æther, fais-moi une faveur et disparait !"
|
||||||
|
},
|
||||||
|
"victory": {
|
||||||
|
"1": "C’est plutôt toi qui devrait m’apprendre à en mettre…",
|
||||||
|
"2": "Pardon ? J’ai pas compris…",
|
||||||
|
"3": "Peu importe les ordres, jamais j’aurais pu te retenir en fait…",
|
||||||
|
"4": "Mhh… Il semblerait que j’ai perdu.",
|
||||||
|
"5": "C’est 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à, l’homme supposé être la dernière ligne défense du Paradis Æther doit affronter un mioche ?",
|
||||||
|
"2_female": "Donc là, l’homme supposé être la dernière ligne défense du Paradis Æther doit affronter un mioche ?",
|
||||||
|
"3": "S’il n’y a qu’un seul nom à retenir au sein de la Fondation Æther, c’est le mien : Saubohne !"
|
||||||
|
},
|
||||||
|
"victory": {
|
||||||
|
"1": "Gloups !",
|
||||||
|
"2": "Malheur ! J’ai perdu face à un simple enfant ?!",
|
||||||
|
"2_female": "Malheur ! J’ai perdu face à une simple enfant ?!",
|
||||||
|
"3": "J’ai 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, j’hallucine ! T’es allé trop loin, le mioche !",
|
||||||
|
"2_female": "Ce manque de respect, j’hallucine ! T’es 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 t’vas jouer frérot.",
|
||||||
|
"4_female": "Pourquoi tu te la joue comme ça ? C'est avec tes dents que t’vas jouer ma reus.",
|
||||||
|
"5": "Cousin, écoute-nous bien ! ♪\nSe taper dessus, ça sert à rien ! ♪\n$Tu t’incrustes chez nous, ça s’fait 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 t’incrustes chez nous, ça s’fait pas ! ♪\n$Mais on est sympa, on a un plan pour toi ! ♪"
|
||||||
|
},
|
||||||
|
"victory": {
|
||||||
|
"1": "Hein ? C’est déjà terminé ?",
|
||||||
|
"2": "… Ça craint grave ! On s’tire !",
|
||||||
|
"3": "Ouais de toute on en avait pas b’soin de ton Pokémon… Ah ah…",
|
||||||
|
"4": "Ouh là, c’est bon, j’en demandais pas tant…",
|
||||||
|
"5": "On pèse plus que des Pokémon, t’entends ?\nAlors tu vas nous respecter, oush !"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"plumeria": {
|
||||||
|
"encounter": {
|
||||||
|
"1": "Tsk. T’es un gamin tout ce qu’il y a de plus banal, en fait.",
|
||||||
|
"1_female": "Tsk. T’es une gamine tout ce qu’il 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 c’qui t’arrive !"
|
||||||
|
},
|
||||||
|
"victory": {
|
||||||
|
"1": "Tsk. T’es pas mauvais. J’te l’accorde.",
|
||||||
|
"1_female": "Tsk. T’es pas mauvaise. J’te l’accorde.",
|
||||||
|
"2": "Tsk. J’dois reconnaitre que t’en as dans le ventre.\n$Maintenant, j’comprends pourquoi mes gars n’arrêtent pas de se faire battre par toi.",
|
||||||
|
"3": "Tsk. J’crois que j'ai plus qu’à assumer ma défaite."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"macro_grunt": {
|
||||||
|
"encounter": {
|
||||||
|
"1": "Hop hop hop ! Terminus !",
|
||||||
|
"2": "T’es un Dresseur n’est-ce pas ?\n$J’ai bien peur ce que ne soit pas une excuse suffisante pour nous interrompre dans notre travail.",
|
||||||
|
"2_female": "T’es une Dresseuse n’est-ce pas ?\n$J’ai bien peur ce que ne soit pas une excuse suffisante pour nous interrompre dans notre travail.",
|
||||||
|
"3": "Je travaille à Macro Cosmos Assurances !\nBesoin d’une assurance-vie ?"
|
||||||
|
},
|
||||||
|
"victory": {
|
||||||
|
"1": "Je n’ai d’autre 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 n’est 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 n’aurais pas dû sous-estimer un Dresseur de ton calibre…",
|
||||||
|
"2_female": "Ah ! Quelle erreur… Je n’aurais 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é, c’est mértié.",
|
"1": "Bien joué, c’est mérité.",
|
||||||
"2": "Dommage, on s’amusait si bien…",
|
"2": "Dommage, on s’amusait si bien…",
|
||||||
"3": "Oh non, le combat est terminé…",
|
"3": "Oh non, le combat est terminé…",
|
||||||
"4": "Aaah, ça fait du bien !\nMerci, j’en avais besoin."
|
"4": "Aaah, ça fait du bien !\nMerci, j’en 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 m’attendais quand même à un au revoir…\n$@c{smile_eclosed}T’as finalement décidé de réaliser ton rêve ?\nJ’ai peine à y croire.\n$@c{serious_smile_fists}Vu que t’es là, ça te dis un petit combat ?\nJe voudrais quand même m’assurer que t’es prêt.\n$@c{serious_mopen_fists}Surtout ne te retiens pas et donne-moi tout ce que t’as !"
|
"1": "@c{smile}Ah, je te cherchais ! Je savais que t’étais pressée de partir, mais je m’attendais quand même à un au revoir…\n$@c{smile_eclosed}T’as finalement décidé de réaliser ton rêve ?\nJ’ai peine à y croire.\n$@c{serious_smile_fists}Vu que t’es là, ça te dis un petit combat ?\nJe voudrais quand même m’assurer que t’es prête.\n$@c{serious_mopen_fists}Surtout ne te retiens pas et donne-moi tout ce que t’as !"
|
||||||
},
|
},
|
||||||
"victory": {
|
"victory": {
|
||||||
"1": "@c{shock}Wah… Tu m’as vraiment lavé.\nT’es vraiment un débutant ?\n$@c{smile}T’as peut-être eu de la chance, mais…\nPeut-être que t’arriveras jusqu’au bout du chemin.\n$D’ailleurs, le prof m’a demandé de te filer ces objets.\nIls ont l’air sympas.\n$@c{serious_smile_fists}Bonne chance à toi !"
|
"1": "@c{shock}Wah… Tu m’as vraiment lavé.\nT’es vraiment une débutante ?\n$@c{smile}T’as peut-être eu de la chance, mais…\nPeut-être que t’arriveras jusqu’au bout du chemin.\n$D’ailleurs, le prof m’a demandé de te filer ces objets.\nIls ont l’air sympas.\n$@c{serious_smile_fists}Bonne chance à toi !"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"rival_female": {
|
"rival_female": {
|
||||||
"encounter": {
|
"encounter": {
|
||||||
"1": "@c{smile_wave}Ah, te voilà ! Je t’ai cherché partout !\n@c{angry_mopen}On oublie de dire au revoir à sa meilleure amie ?\n$@c{smile_ehalf}T’as décidé de réaliser ton rêve, hein ?\nCe jour est donc vraiment arrivé…\n$@c{smile}Je veux bien te pardonner de m’avoir oubliée,\nà une conditon. @c{smile_wave_wink}Que tu m’affronte !\n$@c{angry_mopen}Donne tout ! Ce serait dommage que ton aventure finisse avant d’avoir commencé, hein ?"
|
"1": "@c{smile_wave}Ah, te voilà ! Je t’ai cherché partout !\n@c{angry_mopen}On oublie de dire au revoir à sa meilleure amie ?\n$@c{smile_ehalf}T’as décidé de réaliser ton rêve, hein ?\nCe jour est donc vraiment arrivé…\n$@c{smile}Je veux bien te pardonner de m’avoir oubliée,\nà une condition. @c{smile_wave_wink}Que tu m’affronte !\n$@c{angry_mopen}Donne tout ! Ce serait dommage que ton aventure finisse avant d’avoir commencé, hein ?"
|
||||||
},
|
},
|
||||||
"victory": {
|
"victory": {
|
||||||
"1": "@c{shock}Tu viens de commencer et t’es déjà si fort ?!@d{96}\n@c{angry}T’as triché non ? Avoue !\n$@c{smile_wave_wink}J’déconne !@d{64} @c{smile_eclosed}J’ai perdu dans les règles…\nJ’ai le sentiment que tu vas très bien t’en sortir.\n$@c{smile}D’ailleurs, 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 t’es déjà si fort ?!@d{96}\n@c{angry}T’as triché non ? Avoue !\n$@c{smile_wave_wink}J’déconne !@d{64} @c{smile_eclosed}J’ai perdu dans les règles…\nJ’ai le sentiment que tu vas très bien t’en sortir.\n$@c{smile}D’ailleurs, 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 t’es là ?\n@c{smile_eclosed}Toujours invaincu, hein… ?\n$@c{serious_mopen_fists}Je sais que j’ai l’air de t’avoir suivi ici, mais c’est pas complètement vrai.\n$@c{serious_smile_fists}Pour être honnête, ça me démangeait d’avoir une revanche depuis que tu m’as 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 !\nC’est parti !"
|
"1": "@c{smile}Hé, toi aussi t’es là ?\n@c{smile_eclosed}Toujours invaincue, hein… ?\n$@c{serious_mopen_fists}Je sais que j’ai l’air de t’avoir suivie ici, mais c’est pas complètement vrai.\n$@c{serious_smile_fists}Pour être honnête, ça me démangeait d’avoir une revanche depuis que tu m’as 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 !\nC’est parti !"
|
||||||
},
|
},
|
||||||
"victory": {
|
"victory": {
|
||||||
"1": "@c{neutral_eclosed}Oh. Je crois que j’ai trop pris la confiance.\n$@c{smile}Pas grave, c’est OK. Je me doutais que ça arriverait.\n@c{serious_mopen_fists}Je vais juste devoir encore plus m’entrainer !\n\n$@c{smile}Ah, et pas que t’aies réellement besoin d’aide, mais j’ai ça en trop sur moi qui pourrait t’intéresser.\n\n$@c{serious_smile_fists}Mais n’espère plus en avoir d’autres !\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 j’ai trop pris la confiance.\n$@c{smile}Pas grave, c’est OK. Je me doutais que ça arriverait.\n@c{serious_mopen_fists}Je vais juste devoir encore plus m’entrainer !\n\n$@c{smile}Ah, et pas que t’aies réellement besoin d’aide, mais j’ai ça en trop sur moi qui pourrait t’intéresser.\n\n$@c{serious_smile_fists}Mais n’espère plus en avoir d’autres !\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. T’as toujours l’air invaincu. @c{angry_mopen}Eh… Pas mal !\n$@c{angry_mopen}Je sais à quoi tu penses et non, je t’espionne pas.\n@c{smile_eclosed}C’est juste que j’étais aussi dans le coin.\n$@c{smile_ehalf}Heureuse pour toi, mais je veux juste te rappeler que c’est 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, t’as intérêt à tout donner !"
|
"1": "@c{smile_wave}Hé, sympa de te croiser ici. T’as toujours l’air invaincu. @c{angry_mopen}Eh… Pas mal !\n$@c{angry_mopen}Je sais à quoi tu penses et non, je t’espionne pas.\n@c{smile_eclosed}C’est juste que j’étais aussi dans le coin.\n$@c{smile_ehalf}Heureuse pour toi, mais je veux juste te rappeler que c’est 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, t’as 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 m’entrainer !\n$@c{smile_wave}J’ai 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 m’entrainer !\n$@c{smile_wave}J’ai 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 c’est parfois normal de perdre…"
|
"1": "Je suppose que c’est 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}T’es… toujours invaincu ? Incroyable.\n$@c{neutral_eclosed}Tout est devenu un peu… étrange.\nC’est plus pareil sans toi au village.\n$@c{serious}Je sais que c’est égoïste, mais j’ai besoin d’expier ça.\n@c{neutral_eclosed}Je crois que tout ça te dépasse.\n$@c{serious}Ne jamais perdre, c’est juste irréaliste.\nGrandir, c’est parfois aussi savoir perdre.\n$@c{neutral_eclosed}T’as un beau parcours, mais il y a encore tellement à venir et ça va pas s’arranger. @c{neutral}T’es prêt pour ça ?\n$@c{serious_mopen_fists}Si tu l’es, alors prouve-le."
|
"1": "@c{smile}Hé, mais qui voilà ! Ça fait un bail.\n@c{neutral}T’es… toujours invaincue ? Incroyable.\n$@c{neutral_eclosed}Tout est devenu un peu… étrange.\nC’est plus pareil sans toi au village.\n$@c{serious}Je sais que c’est égoïste, mais j’ai besoin d’expier ça.\n@c{neutral_eclosed}Je crois que tout ça te dépasse.\n$@c{serious}Ne jamais perdre, c’est juste irréaliste.\nGrandir, c’est parfois aussi savoir perdre.\n$@c{neutral_eclosed}T’as un beau parcours, mais il y a encore tellement à venir et ça va pas s’arranger. @c{neutral}T’es prête pour ça ?\n$@c{serious_mopen_fists}Si tu l’es, alors prouve-le."
|
||||||
},
|
},
|
||||||
"victory": {
|
"victory": {
|
||||||
"1": "@c{angry_mhalf}C’est lunaire… J’ai presque fait que m’entrainer…\nAlors pourquoi il y a encore un tel écart entre nous ?"
|
"1": "@c{angry_mhalf}C’est lunaire… J’ai presque fait que m’entrainer…\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}J’ai appris à maximiser tout mon potentiel en m’entrainant d’arrachepied.\n$@c{smile}C’est 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 n’a d’importance désormais, pas tant que j’aurai pas gagné.\n$@c{neutral_eclosed}J’ai 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, c’est 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}J’ai appris à maximiser tout mon potentiel en m’entrainant d’arrachepied.\n$@c{smile}C’est 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 n’a d’importance désormais, pas tant que j’aurai pas gagné.\n$@c{neutral_eclosed}J’ai 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, c’est 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}J’ai 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}C’est 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}J’ignore si je serai capable de l’accomplir, mais je ferai tout ce qui est en mon pouvoir.\n$@c{neutral}Cet endroit est terrifiant… Et pourtant il m’a l’air familier, comme si j’y avais déjà mis les pieds.\n$@c{serious_mhalf_fists}Tu ressens la même chose, pas vrai ?\n$@c{serious}… et c’est 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 qu’un lointain souvenir.\n$@c{neutral_eclosed}D’ailleurs, qui peut dire aujourd’hui qu’ils ont pu être réels ?\n$@c{serious_mopen_fists}Il faut que tu persévères. Si tu t’arrêtes, ça n’aura jamais de fin et t’es le seul à en être capable.\n$@c{serious_smile_fists}Difficile de comprendre le sens de tout ça, je sais juste que c’est la réalité.\n$@c{serious_mopen_fists}Si tu ne parviens pas à me battre ici et maintenant, tu n’as aucune chance."
|
"1": "@c{smile_eclosed}Nous y revoilà.\n$@c{neutral}J’ai 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}C’est 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}J’ignore si je serai capable de l’accomplir, mais je ferai tout ce qui est en mon pouvoir.\n$@c{neutral}Cet endroit est terrifiant… Et pourtant il m’a l’air familier, comme si j’y avais déjà mis les pieds.\n$@c{serious_mhalf_fists}Tu ressens la même chose, pas vrai ?\n$@c{serious}… et c’est 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 qu’un lointain souvenir.\n$@c{neutral_eclosed}D’ailleurs, qui peut dire aujourd’hui qu’ils ont pu être réels ?\n$@c{serious_mopen_fists}Il faut que tu persévères. Si tu t’arrêtes, ça n’aura jamais de fin et t’es la seule à en être capable.\n$@c{serious_smile_fists}Difficile de comprendre le sens de tout ça, je sais juste que c’est la réalité.\n$@c{serious_mopen_fists}Si tu ne parviens pas à me battre ici et maintenant, tu n’as aucune chance."
|
||||||
},
|
},
|
||||||
"victory": {
|
"victory": {
|
||||||
"1": "@c{smile_eclosed}J’ai fait ce que j’avais à faire.\n$Promets-moi juste une chose.\n@c{smile}Après avoir réparé ce monde… Rentre à la maison."
|
"1": "@c{smile_eclosed}J’ai fait ce que j’avais à faire.\n$Promets-moi juste une chose.\n@c{smile}Après avoir réparé ce monde… Rentre à la maison."
|
||||||
|
|
|
@ -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"
|
||||||
|
}
|
||||||
|
|