mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-07-05 16:02:20 +02:00
Merge branch 'beta' into starterInfoText-adjustments
This commit is contained in:
commit
8ed5d636ca
14
biome.jsonc
14
biome.jsonc
@ -32,7 +32,6 @@
|
|||||||
// TODO: these files are too big and complex, ignore them until their respective refactors
|
// TODO: these files are too big and complex, ignore them until their respective refactors
|
||||||
"src/data/moves/move.ts",
|
"src/data/moves/move.ts",
|
||||||
"src/data/abilities/ability.ts",
|
"src/data/abilities/ability.ts",
|
||||||
"src/field/pokemon.ts",
|
|
||||||
|
|
||||||
// this file is just too big:
|
// this file is just too big:
|
||||||
"src/data/balance/tms.ts"
|
"src/data/balance/tms.ts"
|
||||||
@ -92,6 +91,19 @@
|
|||||||
"noUselessSwitchCase": "off", // Explicit > Implicit
|
"noUselessSwitchCase": "off", // Explicit > Implicit
|
||||||
"noUselessConstructor": "warn", // TODO: Refactor and make this an error
|
"noUselessConstructor": "warn", // TODO: Refactor and make this an error
|
||||||
"noBannedTypes": "warn" // TODO: Refactor and make this an error
|
"noBannedTypes": "warn" // TODO: Refactor and make this an error
|
||||||
|
},
|
||||||
|
"nursery": {
|
||||||
|
"noRestrictedTypes": {
|
||||||
|
"level": "error",
|
||||||
|
"options": {
|
||||||
|
"types": {
|
||||||
|
"integer": {
|
||||||
|
"message": "This is an alias for 'number' that can provide false impressions of what values can actually be contained in this variable. Use 'number' instead.",
|
||||||
|
"use": "number"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
149
scripts/decrypt-save.js
Normal file
149
scripts/decrypt-save.js
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
import pkg from "crypto-js";
|
||||||
|
const { AES, enc } = pkg;
|
||||||
|
// biome-ignore lint: This is how you import fs from node
|
||||||
|
import * as fs from "node:fs";
|
||||||
|
|
||||||
|
const SAVE_KEY = "x0i2O7WRiANTqPmZ";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A map of condensed keynames to their associated full names
|
||||||
|
* NOTE: Update this if `src/system/game-data#systemShortKeys` ever changes!
|
||||||
|
*/
|
||||||
|
const systemShortKeys = {
|
||||||
|
seenAttr: "$sa",
|
||||||
|
caughtAttr: "$ca",
|
||||||
|
natureAttr: "$na",
|
||||||
|
seenCount: "$s",
|
||||||
|
caughtCount: "$c",
|
||||||
|
hatchedCount: "$hc",
|
||||||
|
ivs: "$i",
|
||||||
|
moveset: "$m",
|
||||||
|
eggMoves: "$em",
|
||||||
|
candyCount: "$x",
|
||||||
|
friendship: "$f",
|
||||||
|
abilityAttr: "$a",
|
||||||
|
passiveAttr: "$pa",
|
||||||
|
valueReduction: "$vr",
|
||||||
|
classicWinCount: "$wc",
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace the shortened key names with their full names
|
||||||
|
* @param {string} dataStr - The string to convert
|
||||||
|
* @returns {string} The string with shortened keynames replaced with full names
|
||||||
|
*/
|
||||||
|
function convertSystemDataStr(dataStr) {
|
||||||
|
const fromKeys = Object.values(systemShortKeys);
|
||||||
|
const toKeys = Object.keys(systemShortKeys);
|
||||||
|
for (const k in fromKeys) {
|
||||||
|
dataStr = dataStr.replace(new RegExp(`${fromKeys[k].replace("$", "\\$")}`, "g"), toKeys[k]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dataStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrypt a save
|
||||||
|
* @param {string} path - The path to the encrypted save file
|
||||||
|
* @returns {string} The decrypted save data
|
||||||
|
*/
|
||||||
|
function decryptSave(path) {
|
||||||
|
// Check if the file exists
|
||||||
|
if (!fs.existsSync(path)) {
|
||||||
|
console.error(`File not found: ${path}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
let fileData;
|
||||||
|
try {
|
||||||
|
fileData = fs.readFileSync(path, "utf8");
|
||||||
|
} catch (e) {
|
||||||
|
switch (e.code) {
|
||||||
|
case "ENOENT":
|
||||||
|
console.error(`File not found: ${path}`);
|
||||||
|
break;
|
||||||
|
case "EACCES":
|
||||||
|
console.error(`Could not open ${path}: Permission denied`);
|
||||||
|
break;
|
||||||
|
case "EISDIR":
|
||||||
|
console.error(`Unable to read ${path} as it is a directory`);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.error(`Error reading file: ${e.message}`);
|
||||||
|
}
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
return convertSystemDataStr(AES.decrypt(fileData, SAVE_KEY).toString(enc.Utf8));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print the usage message and exits */
|
||||||
|
function printUsage() {
|
||||||
|
console.log(`
|
||||||
|
Usage: node decrypt-save.js <encrypted-file> [save-file]
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
file-path Path to the encrypted save file to decrypt.
|
||||||
|
save-file Path to where the decrypted data should be written. If not provided, the decrypted data will be printed to the console.
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-h, --help Show this help message and exit.
|
||||||
|
|
||||||
|
Description:
|
||||||
|
This script decrypts an encrypted pokerogue save file
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write `data` to `filePath`, gracefully communicating errors that arise
|
||||||
|
* @param {string} filePath
|
||||||
|
* @param {string} data
|
||||||
|
*/
|
||||||
|
function writeToFile(filePath, data) {
|
||||||
|
try {
|
||||||
|
fs.writeFileSync(filePath, data);
|
||||||
|
} catch (e) {
|
||||||
|
switch (e.code) {
|
||||||
|
case "EACCES":
|
||||||
|
console.error(`Could not open ${filePath}: Permission denied`);
|
||||||
|
break;
|
||||||
|
case "EISDIR":
|
||||||
|
console.error(`Unable to write to ${filePath} as it is a directory`);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.error(`Error writing file: ${e.message}`);
|
||||||
|
}
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function main() {
|
||||||
|
let args = process.argv.slice(2);
|
||||||
|
// Get options
|
||||||
|
const options = args.filter(arg => arg.startsWith("-"));
|
||||||
|
// get args
|
||||||
|
args = args.filter(arg => !arg.startsWith("-"));
|
||||||
|
|
||||||
|
if (args.length === 0 || options.includes("-h") || options.includes("--help") || args.length > 2) {
|
||||||
|
printUsage();
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
// If the user provided a second argument, check if the file exists already and refuse to write to it.
|
||||||
|
if (args.length === 2) {
|
||||||
|
const destPath = args[1];
|
||||||
|
if (fs.existsSync(destPath)) {
|
||||||
|
console.error(`Refusing to overwrite ${destPath}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, commence decryption.
|
||||||
|
const decrypt = decryptSave(args[0]);
|
||||||
|
|
||||||
|
if (args.length === 1) {
|
||||||
|
process.stdout.write(decrypt);
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
writeToFile(destPath, decrypt);
|
||||||
|
}
|
||||||
|
|
||||||
|
main();
|
@ -7521,7 +7521,7 @@ export class SuppressAbilitiesAttr extends MoveEffectAttr {
|
|||||||
|
|
||||||
/** Causes the effect to fail when the target's ability is unsupressable or already suppressed. */
|
/** Causes the effect to fail when the target's ability is unsupressable or already suppressed. */
|
||||||
getCondition(): MoveConditionFunc {
|
getCondition(): MoveConditionFunc {
|
||||||
return (user, target, move) => target.getAbility().isSuppressable && !target.summonData.abilitySuppressed;
|
return (_user, target, _move) => !target.summonData.abilitySuppressed && (target.getAbility().isSuppressable || (target.hasPassive() && target.getPassiveAbility().isSuppressable));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ import {
|
|||||||
transitionMysteryEncounterIntroVisuals,
|
transitionMysteryEncounterIntroVisuals,
|
||||||
updatePlayerMoney,
|
updatePlayerMoney,
|
||||||
} from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
} from "#app/data/mystery-encounters/utils/encounter-phase-utils";
|
||||||
import { isNullOrUndefined, NumberHolder, randSeedInt, randSeedItem } from "#app/utils/common";
|
import { isNullOrUndefined, randSeedInt, randSeedItem } from "#app/utils/common";
|
||||||
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
import { MysteryEncounterType } from "#enums/mystery-encounter-type";
|
||||||
import { globalScene } from "#app/global-scene";
|
import { globalScene } from "#app/global-scene";
|
||||||
import type MysteryEncounter from "#app/data/mystery-encounters/mystery-encounter";
|
import type MysteryEncounter from "#app/data/mystery-encounters/mystery-encounter";
|
||||||
@ -88,7 +88,7 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter = MysteryEncounterBui
|
|||||||
|
|
||||||
const r = randSeedInt(SHINY_MAGIKARP_WEIGHT);
|
const r = randSeedInt(SHINY_MAGIKARP_WEIGHT);
|
||||||
|
|
||||||
let validEventEncounters = timedEventManager
|
const validEventEncounters = timedEventManager
|
||||||
.getEventEncounters()
|
.getEventEncounters()
|
||||||
.filter(
|
.filter(
|
||||||
s =>
|
s =>
|
||||||
@ -111,22 +111,26 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter = MysteryEncounterBui
|
|||||||
if (
|
if (
|
||||||
r === 0 ||
|
r === 0 ||
|
||||||
((isNullOrUndefined(species.abilityHidden) || species.abilityHidden === Abilities.NONE) &&
|
((isNullOrUndefined(species.abilityHidden) || species.abilityHidden === Abilities.NONE) &&
|
||||||
(validEventEncounters.length === 0))
|
validEventEncounters.length === 0)
|
||||||
) {
|
) {
|
||||||
// If you roll 1%, give shiny Magikarp with random variant
|
// If you roll 1%, give shiny Magikarp with random variant
|
||||||
species = getPokemonSpecies(Species.MAGIKARP);
|
species = getPokemonSpecies(Species.MAGIKARP);
|
||||||
pokemon = new PlayerPokemon(species, 5, 2, undefined, undefined, true);
|
pokemon = new PlayerPokemon(species, 5, 2, undefined, undefined, true);
|
||||||
}
|
} else if (
|
||||||
else if (
|
validEventEncounters.length > 0 &&
|
||||||
(validEventEncounters.length > 0 && (r <= EVENT_THRESHOLD ||
|
(r <= EVENT_THRESHOLD || isNullOrUndefined(species.abilityHidden) || species.abilityHidden === Abilities.NONE)
|
||||||
(isNullOrUndefined(species.abilityHidden) || species.abilityHidden === Abilities.NONE)))
|
|
||||||
) {
|
) {
|
||||||
tries = 0;
|
tries = 0;
|
||||||
do {
|
do {
|
||||||
// If you roll 20%, give event encounter with 3 extra shiny rolls and its HA, if it has one
|
// If you roll 20%, give event encounter with 3 extra shiny rolls and its HA, if it has one
|
||||||
const enc = randSeedItem(validEventEncounters);
|
const enc = randSeedItem(validEventEncounters);
|
||||||
species = getPokemonSpecies(enc.species);
|
species = getPokemonSpecies(enc.species);
|
||||||
pokemon = new PlayerPokemon(species, 5, species.abilityHidden === Abilities.NONE ? undefined : 2, enc.formIndex);
|
pokemon = new PlayerPokemon(
|
||||||
|
species,
|
||||||
|
5,
|
||||||
|
species.abilityHidden === Abilities.NONE ? undefined : 2,
|
||||||
|
enc.formIndex,
|
||||||
|
);
|
||||||
pokemon.trySetShinySeed();
|
pokemon.trySetShinySeed();
|
||||||
pokemon.trySetShinySeed();
|
pokemon.trySetShinySeed();
|
||||||
pokemon.trySetShinySeed();
|
pokemon.trySetShinySeed();
|
||||||
@ -145,15 +149,13 @@ export const ThePokemonSalesmanEncounter: MysteryEncounter = MysteryEncounterBui
|
|||||||
pokemon.trySetShinySeed();
|
pokemon.trySetShinySeed();
|
||||||
pokemon.trySetShinySeed();
|
pokemon.trySetShinySeed();
|
||||||
pokemon.trySetShinySeed();
|
pokemon.trySetShinySeed();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// If there's, and this would never happen, no eligible event encounters with a hidden ability, just do Magikarp
|
// If there's, and this would never happen, no eligible event encounters with a hidden ability, just do Magikarp
|
||||||
species = getPokemonSpecies(Species.MAGIKARP);
|
species = getPokemonSpecies(Species.MAGIKARP);
|
||||||
pokemon = new PlayerPokemon(species, 5, 2, undefined, undefined, true);
|
pokemon = new PlayerPokemon(species, 5, 2, undefined, undefined, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
pokemon = new PlayerPokemon(species, 5, 2, species.formIndex);
|
pokemon = new PlayerPokemon(species, 5, 2, species.formIndex);
|
||||||
}
|
}
|
||||||
pokemon.generateAndPopulateMoveset();
|
pokemon.generateAndPopulateMoveset();
|
||||||
|
@ -224,16 +224,16 @@ export const trainerPartyTemplates = {
|
|||||||
*/
|
*/
|
||||||
export function getEvilGruntPartyTemplate(): TrainerPartyTemplate {
|
export function getEvilGruntPartyTemplate(): TrainerPartyTemplate {
|
||||||
const waveIndex = globalScene.currentBattle?.waveIndex;
|
const waveIndex = globalScene.currentBattle?.waveIndex;
|
||||||
if (waveIndex <= ClassicFixedBossWaves.EVIL_GRUNT_1){
|
if (waveIndex <= ClassicFixedBossWaves.EVIL_GRUNT_1) {
|
||||||
return trainerPartyTemplates.TWO_AVG;
|
return trainerPartyTemplates.TWO_AVG;
|
||||||
}
|
}
|
||||||
if (waveIndex <= ClassicFixedBossWaves.EVIL_GRUNT_2){
|
if (waveIndex <= ClassicFixedBossWaves.EVIL_GRUNT_2) {
|
||||||
return trainerPartyTemplates.THREE_AVG;
|
return trainerPartyTemplates.THREE_AVG;
|
||||||
}
|
}
|
||||||
if (waveIndex <= ClassicFixedBossWaves.EVIL_GRUNT_3){
|
if (waveIndex <= ClassicFixedBossWaves.EVIL_GRUNT_3) {
|
||||||
return trainerPartyTemplates.TWO_AVG_ONE_STRONG;
|
return trainerPartyTemplates.TWO_AVG_ONE_STRONG;
|
||||||
}
|
}
|
||||||
if (waveIndex <= ClassicFixedBossWaves.EVIL_ADMIN_1){
|
if (waveIndex <= ClassicFixedBossWaves.EVIL_ADMIN_1) {
|
||||||
return trainerPartyTemplates.GYM_LEADER_4; // 3avg 1 strong 1 stronger
|
return trainerPartyTemplates.GYM_LEADER_4; // 3avg 1 strong 1 stronger
|
||||||
}
|
}
|
||||||
return trainerPartyTemplates.GYM_LEADER_5; // 3 avg 2 strong 1 stronger
|
return trainerPartyTemplates.GYM_LEADER_5; // 3 avg 2 strong 1 stronger
|
||||||
@ -251,7 +251,7 @@ export function getGymLeaderPartyTemplate() {
|
|||||||
switch (gameMode.modeId) {
|
switch (gameMode.modeId) {
|
||||||
case GameModes.DAILY:
|
case GameModes.DAILY:
|
||||||
if (currentBattle?.waveIndex <= 20) {
|
if (currentBattle?.waveIndex <= 20) {
|
||||||
return trainerPartyTemplates.GYM_LEADER_2
|
return trainerPartyTemplates.GYM_LEADER_2;
|
||||||
}
|
}
|
||||||
return trainerPartyTemplates.GYM_LEADER_3;
|
return trainerPartyTemplates.GYM_LEADER_3;
|
||||||
case GameModes.CHALLENGE: // In the future, there may be a ChallengeType to call here. For now, use classic's.
|
case GameModes.CHALLENGE: // In the future, there may be a ChallengeType to call here. For now, use classic's.
|
||||||
@ -259,13 +259,15 @@ export function getGymLeaderPartyTemplate() {
|
|||||||
if (currentBattle?.waveIndex <= 20) {
|
if (currentBattle?.waveIndex <= 20) {
|
||||||
return trainerPartyTemplates.GYM_LEADER_1; // 1 avg 1 strong
|
return trainerPartyTemplates.GYM_LEADER_1; // 1 avg 1 strong
|
||||||
}
|
}
|
||||||
else if (currentBattle?.waveIndex <= 30) {
|
if (currentBattle?.waveIndex <= 30) {
|
||||||
return trainerPartyTemplates.GYM_LEADER_2; // 1 avg 1 strong 1 stronger
|
return trainerPartyTemplates.GYM_LEADER_2; // 1 avg 1 strong 1 stronger
|
||||||
}
|
}
|
||||||
else if (currentBattle?.waveIndex <= 60) { // 50 and 60
|
// 50 and 60
|
||||||
|
if (currentBattle?.waveIndex <= 60) {
|
||||||
return trainerPartyTemplates.GYM_LEADER_3; // 2 avg 1 strong 1 stronger
|
return trainerPartyTemplates.GYM_LEADER_3; // 2 avg 1 strong 1 stronger
|
||||||
}
|
}
|
||||||
else if (currentBattle?.waveIndex <= 90) { // 80 and 90
|
// 80 and 90
|
||||||
|
if (currentBattle?.waveIndex <= 90) {
|
||||||
return trainerPartyTemplates.GYM_LEADER_4; // 3 avg 1 strong 1 stronger
|
return trainerPartyTemplates.GYM_LEADER_4; // 3 avg 1 strong 1 stronger
|
||||||
}
|
}
|
||||||
// 110+
|
// 110+
|
||||||
|
2349
src/field/pokemon.ts
2349
src/field/pokemon.ts
File diff suppressed because it is too large
Load Diff
@ -24,7 +24,7 @@ export class RevivalBlessingPhase extends BattlePhase {
|
|||||||
UiMode.PARTY,
|
UiMode.PARTY,
|
||||||
PartyUiMode.REVIVAL_BLESSING,
|
PartyUiMode.REVIVAL_BLESSING,
|
||||||
this.user.getFieldIndex(),
|
this.user.getFieldIndex(),
|
||||||
(slotIndex: integer, _option: PartyOption) => {
|
(slotIndex: number, _option: PartyOption) => {
|
||||||
if (slotIndex >= 0 && slotIndex < 6) {
|
if (slotIndex >= 0 && slotIndex < 6) {
|
||||||
const pokemon = globalScene.getPlayerParty()[slotIndex];
|
const pokemon = globalScene.getPlayerParty()[slotIndex];
|
||||||
if (!pokemon || !pokemon.isFainted()) {
|
if (!pokemon || !pokemon.isFainted()) {
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -25,7 +25,7 @@ describe("Moves - Gastro Acid", () => {
|
|||||||
game.override.battleStyle("double");
|
game.override.battleStyle("double");
|
||||||
game.override.startingLevel(1);
|
game.override.startingLevel(1);
|
||||||
game.override.enemyLevel(100);
|
game.override.enemyLevel(100);
|
||||||
game.override.ability(Abilities.NONE);
|
game.override.ability(Abilities.BALL_FETCH);
|
||||||
game.override.moveset([Moves.GASTRO_ACID, Moves.WATER_GUN, Moves.SPLASH, Moves.CORE_ENFORCER]);
|
game.override.moveset([Moves.GASTRO_ACID, Moves.WATER_GUN, Moves.SPLASH, Moves.CORE_ENFORCER]);
|
||||||
game.override.enemySpecies(Species.BIDOOF);
|
game.override.enemySpecies(Species.BIDOOF);
|
||||||
game.override.enemyMoveset(Moves.SPLASH);
|
game.override.enemyMoveset(Moves.SPLASH);
|
||||||
@ -40,7 +40,7 @@ describe("Moves - Gastro Acid", () => {
|
|||||||
* - player mon 1 should have dealt damage, player mon 2 should have not
|
* - player mon 1 should have dealt damage, player mon 2 should have not
|
||||||
*/
|
*/
|
||||||
|
|
||||||
await game.startBattle();
|
await game.classicMode.startBattle();
|
||||||
|
|
||||||
game.move.select(Moves.GASTRO_ACID, 0, BattlerIndex.ENEMY);
|
game.move.select(Moves.GASTRO_ACID, 0, BattlerIndex.ENEMY);
|
||||||
game.move.select(Moves.SPLASH, 1);
|
game.move.select(Moves.SPLASH, 1);
|
||||||
@ -63,7 +63,7 @@ describe("Moves - Gastro Acid", () => {
|
|||||||
it("fails if used on an enemy with an already-suppressed ability", async () => {
|
it("fails if used on an enemy with an already-suppressed ability", async () => {
|
||||||
game.override.battleStyle("single");
|
game.override.battleStyle("single");
|
||||||
|
|
||||||
await game.startBattle();
|
await game.classicMode.startBattle();
|
||||||
|
|
||||||
game.move.select(Moves.CORE_ENFORCER);
|
game.move.select(Moves.CORE_ENFORCER);
|
||||||
// Force player to be slower to enable Core Enforcer to proc its suppression effect
|
// Force player to be slower to enable Core Enforcer to proc its suppression effect
|
||||||
@ -77,4 +77,27 @@ describe("Moves - Gastro Acid", () => {
|
|||||||
|
|
||||||
expect(game.scene.getPlayerPokemon()!.getLastXMoves()[0].result).toBe(MoveResult.FAIL);
|
expect(game.scene.getPlayerPokemon()!.getLastXMoves()[0].result).toBe(MoveResult.FAIL);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should suppress the passive of a target even if its main ability is unsuppressable and not suppress main abli", async () => {
|
||||||
|
game.override
|
||||||
|
.enemyAbility(Abilities.COMATOSE)
|
||||||
|
.enemyPassiveAbility(Abilities.WATER_ABSORB)
|
||||||
|
.moveset([Moves.SPLASH, Moves.GASTRO_ACID, Moves.WATER_GUN]);
|
||||||
|
await game.classicMode.startBattle([Species.MAGIKARP]);
|
||||||
|
|
||||||
|
const enemyPokemon = game.scene.getEnemyPokemon();
|
||||||
|
|
||||||
|
game.move.select(Moves.GASTRO_ACID);
|
||||||
|
await game.toNextTurn();
|
||||||
|
expect(enemyPokemon?.summonData.abilitySuppressed).toBe(true);
|
||||||
|
|
||||||
|
game.move.select(Moves.WATER_GUN);
|
||||||
|
await game.toNextTurn();
|
||||||
|
expect(enemyPokemon?.getHpRatio()).toBeLessThan(1);
|
||||||
|
|
||||||
|
game.move.select(Moves.SPORE);
|
||||||
|
await game.phaseInterceptor.to("BerryPhase");
|
||||||
|
|
||||||
|
expect(enemyPokemon?.status?.effect).toBeFalsy();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user