diff --git a/public/locales b/public/locales index 6b3f37cb351..b4534f03ba8 160000 --- a/public/locales +++ b/public/locales @@ -1 +1 @@ -Subproject commit 6b3f37cb351552721232f4dabefa17bddb5b9004 +Subproject commit b4534f03ba8eb8709486ee967257b6f3725702dd diff --git a/src/data/challenge.ts b/src/data/challenge.ts index 9a60a41b2d2..00d96fd94fe 100644 --- a/src/data/challenge.ts +++ b/src/data/challenge.ts @@ -285,11 +285,7 @@ export abstract class Challenge { * @param _dexAttr {@link DexAttrProps} The dex attributes of the pokemon. * @returns {@link boolean} Whether this function did anything. */ - applyStarterChoice( - _pokemon: PokemonSpecies, - _valid: Utils.BooleanHolder, - _dexAttr: DexAttrProps, - ): boolean { + applyStarterChoice(_pokemon: PokemonSpecies, _valid: Utils.BooleanHolder, _dexAttr: DexAttrProps): boolean { return false; } @@ -441,10 +437,7 @@ export class SingleGenerationChallenge extends Challenge { super(Challenges.SINGLE_GENERATION, 9); } - applyStarterChoice( - pokemon: PokemonSpecies, - valid: Utils.BooleanHolder, - ): boolean { + applyStarterChoice(pokemon: PokemonSpecies, valid: Utils.BooleanHolder): boolean { if (pokemon.generation !== this.value) { valid.value = false; return true; @@ -725,13 +718,9 @@ export class SingleTypeChallenge extends Challenge { super(Challenges.SINGLE_TYPE, 18); } - override applyStarterChoice( - pokemon: PokemonSpecies, - valid: Utils.BooleanHolder, - dexAttr: DexAttrProps, - ): boolean { + override applyStarterChoice(pokemon: PokemonSpecies, valid: Utils.BooleanHolder, dexAttr: DexAttrProps): boolean { const speciesForm = getPokemonSpeciesForm(pokemon.speciesId, dexAttr.formIndex); - const types = [ speciesForm.type1, speciesForm.type2 ]; + const types = [speciesForm.type1, speciesForm.type2]; if (!types.includes(this.value - 1)) { valid.value = false; return true; diff --git a/src/ui/starter-select-ui-handler.ts b/src/ui/starter-select-ui-handler.ts index 6c19553f34b..1f834774650 100644 --- a/src/ui/starter-select-ui-handler.ts +++ b/src/ui/starter-select-ui-handler.ts @@ -1569,53 +1569,52 @@ export default class StarterSelectUiHandler extends MessageUiHandler { Challenge.ChallengeType.STARTER_CHOICE, species, isValidForChallenge, - props + props, ); return isValidForChallenge.value; - } else { - // We check the validity of every evolution and battle form separately, - // and require that at least one is valid - const allValidities: boolean[] = []; - const speciesToCheck = [ species.speciesId ]; - while (speciesToCheck.length) { - const checking = speciesToCheck.pop(); - const checkingSpecies = getPokemonSpecies(checking ?? Species.BULBASAUR); - const isEvoValidForChallenge = new BooleanHolder(true); - Challenge.applyChallenges( - globalScene.gameMode, - Challenge.ChallengeType.STARTER_CHOICE, - checkingSpecies, - isEvoValidForChallenge, - props // This might be wrong, in principle we need to pass the right formIndex - ); - allValidities.push(isEvoValidForChallenge.value); - if (checking && pokemonEvolutions.hasOwnProperty(checking)) { - pokemonEvolutions[checking].forEach(e => { - speciesToCheck.push(e.speciesId); - }); - } - if (checking && pokemonFormChanges.hasOwnProperty(checking)) { - pokemonFormChanges[checking].forEach(f1 => { - checkingSpecies.forms.forEach((f2, formIndex) => { - if (f1.formKey === f2.formKey) { - const formProps = { ...props }; - formProps.formIndex = formIndex; - const isFormValidForChallenge = new BooleanHolder(true); - Challenge.applyChallenges( - globalScene.gameMode, - Challenge.ChallengeType.STARTER_CHOICE, - checkingSpecies, - isFormValidForChallenge, - formProps - ); - allValidities.push(isFormValidForChallenge.value); - } - }); - }); - } - } - return allValidities.filter(v => v).length > 0; } + // We check the validity of every evolution and battle form separately, + // and require that at least one is valid + const allValidities: boolean[] = []; + const speciesToCheck = [species.speciesId]; + while (speciesToCheck.length) { + const checking = speciesToCheck.pop(); + const checkingSpecies = getPokemonSpecies(checking ?? Species.BULBASAUR); + const isEvoValidForChallenge = new BooleanHolder(true); + Challenge.applyChallenges( + globalScene.gameMode, + Challenge.ChallengeType.STARTER_CHOICE, + checkingSpecies, + isEvoValidForChallenge, + props, // This might be wrong, in principle we need to pass the right formIndex + ); + allValidities.push(isEvoValidForChallenge.value); + if (checking && pokemonEvolutions.hasOwnProperty(checking)) { + pokemonEvolutions[checking].forEach(e => { + speciesToCheck.push(e.speciesId); + }); + } + if (checking && pokemonFormChanges.hasOwnProperty(checking)) { + pokemonFormChanges[checking].forEach(f1 => { + checkingSpecies.forms.forEach((f2, formIndex) => { + if (f1.formKey === f2.formKey) { + const formProps = { ...props }; + formProps.formIndex = formIndex; + const isFormValidForChallenge = new BooleanHolder(true); + Challenge.applyChallenges( + globalScene.gameMode, + Challenge.ChallengeType.STARTER_CHOICE, + checkingSpecies, + isFormValidForChallenge, + formProps, + ); + allValidities.push(isFormValidForChallenge.value); + } + }); + }); + } + } + return allValidities.filter(v => v).length > 0; } processInput(button: Button): boolean { @@ -1831,10 +1830,7 @@ export default class StarterSelectUiHandler extends MessageUiHandler { ); const isCaught = globalScene.gameData.dexData[species.speciesId].caughtAttr; return ( - !isDupe && - isValidForChallenge && - currentPartyValue + starterCost <= this.getValueLimit() && - isCaught + !isDupe && isValidForChallenge && currentPartyValue + starterCost <= this.getValueLimit() && isCaught ); }); if (validStarters.length === 0) { @@ -1926,7 +1922,10 @@ export default class StarterSelectUiHandler extends MessageUiHandler { const isPartyValid = this.isPartyValid(); const isValidForChallenge = this.checkValidForChallenge( this.lastSpecies, - globalScene.gameData.getSpeciesDexAttrProps(this.lastSpecies, this.getCurrentDexProps(this.lastSpecies.speciesId)), + globalScene.gameData.getSpeciesDexAttrProps( + this.lastSpecies, + this.getCurrentDexProps(this.lastSpecies.speciesId), + ), isPartyValid, ); @@ -3046,11 +3045,22 @@ export default class StarterSelectUiHandler extends MessageUiHandler { * Since some pokemon rely on forms to be valid (i.e. blaze tauros for fire challenges), we make a fake form and dex props to use in the challenge */ const tempFormProps = BigInt(Math.pow(2, i)) * DexAttr.DEFAULT_FORM; - const isValidForChallenge = this.checkValidForChallenge(container.species, globalScene.gameData.getSpeciesDexAttrProps(species, tempFormProps), true); + const isValidForChallenge = this.checkValidForChallenge( + container.species, + globalScene.gameData.getSpeciesDexAttrProps(species, tempFormProps), + true, + ); allFormsValid = allFormsValid || isValidForChallenge; } } else { - const isValidForChallenge = this.checkValidForChallenge(container.species, globalScene.gameData.getSpeciesDexAttrProps(species, globalScene.gameData.getSpeciesDefaultDexAttr(container.species, false, true)), true); + const isValidForChallenge = this.checkValidForChallenge( + container.species, + globalScene.gameData.getSpeciesDexAttrProps( + species, + globalScene.gameData.getSpeciesDefaultDexAttr(container.species, false, true), + ), + true, + ); allFormsValid = isValidForChallenge; } if (allFormsValid) { @@ -3884,7 +3894,9 @@ export default class StarterSelectUiHandler extends MessageUiHandler { this.pokemonSprite.setVisible(!this.statsMode); } - const currentFilteredContainer = this.filteredStarterContainers.find(p => p.species.speciesId === species.speciesId); + const currentFilteredContainer = this.filteredStarterContainers.find( + p => p.species.speciesId === species.speciesId, + ); if (currentFilteredContainer) { const starterSprite = currentFilteredContainer.icon as Phaser.GameObjects.Sprite; starterSprite.setTexture( @@ -4259,7 +4271,11 @@ export default class StarterSelectUiHandler extends MessageUiHandler { if (addingToParty) { // this does a check to see if the pokemon being added is valid; if so, it will update the isPartyValid boolean const species = this.filteredStarterContainers[this.cursor].species; - const isNewPokemonValid = this.checkValidForChallenge(species, globalScene.gameData.getSpeciesDexAttrProps(species, this.getCurrentDexProps(species.speciesId)), false); + const isNewPokemonValid = this.checkValidForChallenge( + species, + globalScene.gameData.getSpeciesDexAttrProps(species, this.getCurrentDexProps(species.speciesId)), + false, + ); isPartyValid = isPartyValid || isNewPokemonValid; } @@ -4284,7 +4300,14 @@ export default class StarterSelectUiHandler extends MessageUiHandler { * If speciesStarterDexEntry?.caughtAttr is true, this species registered in stater. * we change to can AddParty value to true since the user has enough cost to choose this pokemon and this pokemon registered too. */ - const isValidForChallenge = this.checkValidForChallenge(this.allSpecies[s], globalScene.gameData.getSpeciesDexAttrProps(this.allSpecies[s], this.getCurrentDexProps(this.allSpecies[s].speciesId)), isPartyValid); + const isValidForChallenge = this.checkValidForChallenge( + this.allSpecies[s], + globalScene.gameData.getSpeciesDexAttrProps( + this.allSpecies[s], + this.getCurrentDexProps(this.allSpecies[s].speciesId), + ), + isPartyValid, + ); const canBeChosen = remainValue >= speciesStarterValue && isValidForChallenge; @@ -4421,7 +4444,11 @@ export default class StarterSelectUiHandler extends MessageUiHandler { let canStart = false; for (let s = 0; s < this.starterSpecies.length; s++) { const species = this.starterSpecies[s]; - const isValidForChallenge = this.checkValidForChallenge(species, globalScene.gameData.getSpeciesDexAttrProps(species, this.getCurrentDexProps(species.speciesId)), false); + const isValidForChallenge = this.checkValidForChallenge( + species, + globalScene.gameData.getSpeciesDexAttrProps(species, this.getCurrentDexProps(species.speciesId)), + false, + ); canStart = canStart || isValidForChallenge; } return canStart; diff --git a/test/abilities/lightningrod.test.ts b/test/abilities/lightningrod.test.ts index 1ca6c6b1e89..986899353ff 100644 --- a/test/abilities/lightningrod.test.ts +++ b/test/abilities/lightningrod.test.ts @@ -24,7 +24,7 @@ describe("Abilities - Lightningrod", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override - .moveset([ Moves.SPLASH, Moves.SHOCK_WAVE ]) + .moveset([Moves.SPLASH, Moves.SHOCK_WAVE]) .ability(Abilities.BALL_FETCH) .battleType("double") .disableCrits() @@ -34,7 +34,7 @@ describe("Abilities - Lightningrod", () => { }); it("should redirect electric type moves", async () => { - await game.classicMode.startBattle([ Species.FEEBAS, Species.MAGIKARP ]); + await game.classicMode.startBattle([Species.FEEBAS, Species.MAGIKARP]); const enemy1 = game.scene.getEnemyField()[0]; const enemy2 = game.scene.getEnemyField()[1]; @@ -49,8 +49,8 @@ describe("Abilities - Lightningrod", () => { }); it("should not redirect non-electric type moves", async () => { - game.override.moveset([ Moves.SPLASH, Moves.AERIAL_ACE ]); - await game.classicMode.startBattle([ Species.FEEBAS, Species.MAGIKARP ]); + game.override.moveset([Moves.SPLASH, Moves.AERIAL_ACE]); + await game.classicMode.startBattle([Species.FEEBAS, Species.MAGIKARP]); const enemy1 = game.scene.getEnemyField()[0]; const enemy2 = game.scene.getEnemyField()[1]; @@ -65,7 +65,7 @@ describe("Abilities - Lightningrod", () => { }); it("should boost the user's spatk without damaging", async () => { - await game.classicMode.startBattle([ Species.FEEBAS, Species.MAGIKARP ]); + await game.classicMode.startBattle([Species.FEEBAS, Species.MAGIKARP]); const enemy2 = game.scene.getEnemyField()[1]; @@ -81,7 +81,7 @@ describe("Abilities - Lightningrod", () => { it("should not redirect moves changed from electric type via ability", async () => { game.override.ability(Abilities.NORMALIZE); - await game.classicMode.startBattle([ Species.FEEBAS, Species.MAGIKARP ]); + await game.classicMode.startBattle([Species.FEEBAS, Species.MAGIKARP]); const enemy1 = game.scene.getEnemyField()[0]; const enemy2 = game.scene.getEnemyField()[1]; @@ -96,9 +96,8 @@ describe("Abilities - Lightningrod", () => { }); it("should redirect moves changed to electric type via ability", async () => { - game.override.ability(Abilities.GALVANIZE) - .moveset(Moves.TACKLE); - await game.classicMode.startBattle([ Species.FEEBAS, Species.MAGIKARP ]); + game.override.ability(Abilities.GALVANIZE).moveset(Moves.TACKLE); + await game.classicMode.startBattle([Species.FEEBAS, Species.MAGIKARP]); const enemy1 = game.scene.getEnemyField()[0]; const enemy2 = game.scene.getEnemyField()[1]; diff --git a/test/abilities/neutralizing_gas.test.ts b/test/abilities/neutralizing_gas.test.ts index 08ab884d806..dbb4b0562be 100644 --- a/test/abilities/neutralizing_gas.test.ts +++ b/test/abilities/neutralizing_gas.test.ts @@ -158,11 +158,8 @@ describe("Abilities - Neutralizing Gas", () => { }); it("should not activate abilities of pokemon no longer on the field", async () => { - game.override - .battleType("single") - .ability(Abilities.NEUTRALIZING_GAS) - .enemyAbility(Abilities.DELTA_STREAM); - await game.classicMode.startBattle([ Species.MAGIKARP ]); + game.override.battleType("single").ability(Abilities.NEUTRALIZING_GAS).enemyAbility(Abilities.DELTA_STREAM); + await game.classicMode.startBattle([Species.MAGIKARP]); const enemy = game.scene.getEnemyPokemon()!; const weatherChangeAttr = enemy.getAbilityAttrs(PostSummonWeatherChangeAbAttr, false)[0]; diff --git a/test/abilities/storm_drain.test.ts b/test/abilities/storm_drain.test.ts index e2a7b3e212e..58ff477fa43 100644 --- a/test/abilities/storm_drain.test.ts +++ b/test/abilities/storm_drain.test.ts @@ -24,7 +24,7 @@ describe("Abilities - Storm Drain", () => { beforeEach(() => { game = new GameManager(phaserGame); game.override - .moveset([ Moves.SPLASH, Moves.WATER_GUN ]) + .moveset([Moves.SPLASH, Moves.WATER_GUN]) .ability(Abilities.BALL_FETCH) .battleType("double") .disableCrits() @@ -34,7 +34,7 @@ describe("Abilities - Storm Drain", () => { }); it("should redirect water type moves", async () => { - await game.classicMode.startBattle([ Species.FEEBAS, Species.MAGIKARP ]); + await game.classicMode.startBattle([Species.FEEBAS, Species.MAGIKARP]); const enemy1 = game.scene.getEnemyField()[0]; const enemy2 = game.scene.getEnemyField()[1]; @@ -49,8 +49,8 @@ describe("Abilities - Storm Drain", () => { }); it("should not redirect non-water type moves", async () => { - game.override.moveset([ Moves.SPLASH, Moves.AERIAL_ACE ]); - await game.classicMode.startBattle([ Species.FEEBAS, Species.MAGIKARP ]); + game.override.moveset([Moves.SPLASH, Moves.AERIAL_ACE]); + await game.classicMode.startBattle([Species.FEEBAS, Species.MAGIKARP]); const enemy1 = game.scene.getEnemyField()[0]; const enemy2 = game.scene.getEnemyField()[1]; @@ -65,7 +65,7 @@ describe("Abilities - Storm Drain", () => { }); it("should boost the user's spatk without damaging", async () => { - await game.classicMode.startBattle([ Species.FEEBAS, Species.MAGIKARP ]); + await game.classicMode.startBattle([Species.FEEBAS, Species.MAGIKARP]); const enemy2 = game.scene.getEnemyField()[1]; @@ -81,7 +81,7 @@ describe("Abilities - Storm Drain", () => { it("should not redirect moves changed from water type via ability", async () => { game.override.ability(Abilities.NORMALIZE); - await game.classicMode.startBattle([ Species.FEEBAS, Species.MAGIKARP ]); + await game.classicMode.startBattle([Species.FEEBAS, Species.MAGIKARP]); const enemy1 = game.scene.getEnemyField()[0]; const enemy2 = game.scene.getEnemyField()[1]; @@ -96,9 +96,8 @@ describe("Abilities - Storm Drain", () => { }); it("should redirect moves changed to water type via ability", async () => { - game.override.ability(Abilities.LIQUID_VOICE) - .moveset(Moves.PSYCHIC_NOISE); - await game.classicMode.startBattle([ Species.FEEBAS, Species.MAGIKARP ]); + game.override.ability(Abilities.LIQUID_VOICE).moveset(Moves.PSYCHIC_NOISE); + await game.classicMode.startBattle([Species.FEEBAS, Species.MAGIKARP]); const enemy1 = game.scene.getEnemyField()[0]; const enemy2 = game.scene.getEnemyField()[1];