diff --git a/src/battle-scene.ts b/src/battle-scene.ts index 2f062667808..62e9d8ea717 100644 --- a/src/battle-scene.ts +++ b/src/battle-scene.ts @@ -3008,7 +3008,8 @@ export default class BattleScene extends SceneBase { } validateAchv(achv: Achv, args?: unknown[]): boolean { - if (!this.gameData.achvUnlocks.hasOwnProperty(achv.id) && achv.validate(this, args)) { + if ((!this.gameData.achvUnlocks.hasOwnProperty(achv.id) || Overrides.ACHIEVEMENTS_REUNLOCK_OVERRIDE) + && achv.validate(this, args)) { this.gameData.achvUnlocks[achv.id] = new Date().getTime(); this.ui.achvBar.showAchv(achv); if (vouchers.hasOwnProperty(achv.id)) { diff --git a/src/data/mystery-encounters/encounters/the-expert-pokemon-breeder-encounter.ts b/src/data/mystery-encounters/encounters/the-expert-pokemon-breeder-encounter.ts index 6a4c6592fda..5ac9852f27a 100644 --- a/src/data/mystery-encounters/encounters/the-expert-pokemon-breeder-encounter.ts +++ b/src/data/mystery-encounters/encounters/the-expert-pokemon-breeder-encounter.ts @@ -21,7 +21,6 @@ import { EggSourceType } from "#enums/egg-source-types"; import { EggTier } from "#enums/egg-type"; import { MysteryEncounterOptionBuilder } from "#app/data/mystery-encounters/mystery-encounter-option"; import { MysteryEncounterOptionMode } from "#enums/mystery-encounter-option-mode"; -import { achvs } from "#app/system/achv"; import { modifierTypes, PokemonHeldItemModifierType } from "#app/modifier/modifier-type"; import { Type } from "#enums/type"; import { getPokeballTintColor } from "#app/data/pokeball"; @@ -520,12 +519,6 @@ function removePokemonFromPartyAndStoreHeldItems(scene: BattleScene, encounter: ]; } -function checkAchievement(scene: BattleScene) { - if (scene.arena.biomeType === Biome.SPACE) { - scene.validateAchv(achvs.BREEDERS_IN_SPACE); - } -} - function restorePartyAndHeldItems(scene: BattleScene) { const encounter = scene.currentBattle.mysteryEncounter!; // Restore original party @@ -617,8 +610,6 @@ function onGameOver(scene: BattleScene) { function doPostEncounterCleanup(scene: BattleScene) { const encounter = scene.currentBattle.mysteryEncounter!; if (!encounter.misc.encounterFailed) { - // Give achievement if in Space biome - checkAchievement(scene); // Give 20 friendship to the chosen pokemon encounter.misc.chosenPokemon.addFriendship(FRIENDSHIP_ADDED); restorePartyAndHeldItems(scene); diff --git a/src/overrides.ts b/src/overrides.ts index 7b73cd47b03..dc166307314 100644 --- a/src/overrides.ts +++ b/src/overrides.ts @@ -86,6 +86,8 @@ class DefaultOverrides { readonly ITEM_UNLOCK_OVERRIDE: Unlockables[] = []; /** Set to `true` to show all tutorials */ readonly BYPASS_TUTORIAL_SKIP_OVERRIDE: boolean = false; + /** Set to `true` to be able to re-earn already unlocked achievements */ + readonly ACHIEVEMENTS_REUNLOCK_OVERRIDE: boolean = false; /** Set to `true` to force Paralysis and Freeze to always activate, or `false` to force them to not activate */ readonly STATUS_ACTIVATION_OVERRIDE: boolean | null = null; diff --git a/src/phases/trainer-victory-phase.ts b/src/phases/trainer-victory-phase.ts index dc1b962f47e..d797e4360ac 100644 --- a/src/phases/trainer-victory-phase.ts +++ b/src/phases/trainer-victory-phase.ts @@ -9,6 +9,8 @@ import { BattlePhase } from "./battle-phase"; import { ModifierRewardPhase } from "./modifier-reward-phase"; import { MoneyRewardPhase } from "./money-reward-phase"; import { TrainerSlot } from "#app/data/trainer-config"; +import { Biome } from "#app/enums/biome"; +import { achvs } from "#app/system/achv"; export class TrainerVictoryPhase extends BattlePhase { constructor(scene: BattleScene) { @@ -34,11 +36,17 @@ export class TrainerVictoryPhase extends BattlePhase { } const trainerType = this.scene.currentBattle.trainer?.config.trainerType!; // TODO: is this bang correct? + // Validate Voucher for boss trainers if (vouchers.hasOwnProperty(TrainerType[trainerType])) { if (!this.scene.validateVoucher(vouchers[TrainerType[trainerType]]) && this.scene.currentBattle.trainer?.config.isBoss) { this.scene.unshiftPhase(new ModifierRewardPhase(this.scene, [ modifierTypes.VOUCHER, modifierTypes.VOUCHER, modifierTypes.VOUCHER_PLUS, modifierTypes.VOUCHER_PREMIUM ][vouchers[TrainerType[trainerType]].voucherType])); } } + // Breeders in Space achievement + if (this.scene.arena.biomeType === Biome.SPACE + && (trainerType === TrainerType.BREEDER || trainerType === TrainerType.EXPERT_POKEMON_BREEDER)) { + this.scene.validateAchv(achvs.BREEDERS_IN_SPACE); + } this.scene.ui.showText(i18next.t("battle:trainerDefeated", { trainerName: this.scene.currentBattle.trainer?.getName(TrainerSlot.NONE, true) }), null, () => { const victoryMessages = this.scene.currentBattle.trainer?.getVictoryMessages()!; // TODO: is this bang correct? diff --git a/src/system/achv.ts b/src/system/achv.ts index d94fcba48f2..a98e396264d 100644 --- a/src/system/achv.ts +++ b/src/system/achv.ts @@ -358,7 +358,7 @@ export const achvs = { MONO_FAIRY: new ChallengeAchv("MONO_FAIRY", "", "MONO_FAIRY.description", "fairy_feather", 100, (c, scene) => c instanceof SingleTypeChallenge && c.value === 18 && !scene.gameMode.challenges.some(c => c.id === Challenges.INVERSE_BATTLE && c.value > 0)), FRESH_START: new ChallengeAchv("FRESH_START", "", "FRESH_START.description", "reviver_seed", 100, (c, scene) => c instanceof FreshStartChallenge && c.value > 0 && !scene.gameMode.challenges.some(c => c.id === Challenges.INVERSE_BATTLE && c.value > 0)), INVERSE_BATTLE: new ChallengeAchv("INVERSE_BATTLE", "", "INVERSE_BATTLE.description", "inverse", 100, c => c instanceof InverseBattleChallenge && c.value > 0), - BREEDERS_IN_SPACE: new Achv("BREEDERS_IN_SPACE", "", "BREEDERS_IN_SPACE.description", "moon_stone", 100).setSecret(), + BREEDERS_IN_SPACE: new Achv("BREEDERS_IN_SPACE", "", "BREEDERS_IN_SPACE.description", "moon_stone", 50).setSecret(), }; export function initAchievements() {