diff --git a/src/data/ability.ts b/src/data/ability.ts index 95bb6b8d54e..f8c26f9e516 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -2865,7 +2865,7 @@ export class PreSetStatusEffectImmunityAbAttr extends PreSetStatusAbAttr { * @returns A boolean indicating the result of the status application. */ applyPreSetStatus(pokemon: Pokemon, passive: boolean, simulated: boolean, effect: StatusEffect, cancelled: Utils.BooleanHolder, args: any[]): boolean { - if (this.immuneEffects.length < 1 || this.immuneEffects.includes(effect)) { + if (effect !== StatusEffect.FAINT && this.immuneEffects.length < 1 || this.immuneEffects.includes(effect)) { cancelled.value = true; return true; } diff --git a/src/data/balance/biomes.ts b/src/data/balance/biomes.ts index 240881ad580..8913fd47e93 100644 --- a/src/data/balance/biomes.ts +++ b/src/data/balance/biomes.ts @@ -102,6 +102,18 @@ export interface BiomePokemonPools { [key: integer]: BiomeTierPokemonPools } +export interface BiomeTierTod { + biome: Biome, + tier: BiomePoolTier, + tod: TimeOfDay[] +} + +export interface CatchableSpecies{ + [key: integer]: BiomeTierTod[] +} + +export const catchableSpecies: CatchableSpecies = {}; + export interface BiomeTierTrainerPools { [key: integer]: TrainerType[] } @@ -7716,6 +7728,9 @@ export function initBiomes() { uncatchableSpecies.push(speciesId); } + // array of biome options for the current species + catchableSpecies[speciesId] = []; + for (const b of biomeEntries) { const biome = b[0]; const tier = b[1]; @@ -7725,6 +7740,12 @@ export function initBiomes() { : [ b[2] ] : [ TimeOfDay.ALL ]; + catchableSpecies[speciesId].push({ + biome: biome as Biome, + tier: tier as BiomePoolTier, + tod: timesOfDay as TimeOfDay[] + }); + for (const tod of timesOfDay) { if (!biomePokemonPools.hasOwnProperty(biome) || !biomePokemonPools[biome].hasOwnProperty(tier) || !biomePokemonPools[biome][tier].hasOwnProperty(tod)) { continue; diff --git a/src/data/balance/passives.ts b/src/data/balance/passives.ts index 60b50c7909c..f28b8bbdeea 100644 --- a/src/data/balance/passives.ts +++ b/src/data/balance/passives.ts @@ -1,7 +1,15 @@ import { Abilities } from "#app/enums/abilities"; import { Species } from "#app/enums/species"; -export const starterPassiveAbilities = { +export interface PassiveAbilities { + [key: number]: Abilities +} + +interface StarterPassiveAbilities { + [key: integer]: PassiveAbilities +} + +export const starterPassiveAbilities: StarterPassiveAbilities = { [Species.BULBASAUR]: { 0: Abilities.GRASSY_SURGE }, [Species.CHARMANDER]: { 0: Abilities.BEAST_BOOST }, [Species.SQUIRTLE]: { 0: Abilities.STURDY }, diff --git a/src/data/balance/tms.ts b/src/data/balance/tms.ts index da900768987..e44f7bf44bf 100644 --- a/src/data/balance/tms.ts +++ b/src/data/balance/tms.ts @@ -68433,6 +68433,46 @@ export const tmSpecies: TmSpecies = { ], }; +interface SpeciesTmMoves { + [key: integer]: (Moves | [string | Species, Moves])[]; +} + +function transposeTmSpecies(): SpeciesTmMoves { + const flipped: SpeciesTmMoves = {}; + + for (const move in tmSpecies) { + const moveKey = Number(move); + const speciesList = tmSpecies[move]; + + for (const species of speciesList) { + + if (Array.isArray(species)) { + // Extract base species and all associated forms + const [ baseSpecies, ...forms ] = species; + const speciesKey = Number(baseSpecies); + + if (!flipped[speciesKey]) { + flipped[speciesKey] = []; + } + + for (const form of forms) { + flipped[speciesKey].push([ form, moveKey ]); + } + + } else { + const speciesKey = Number(species); + if (!flipped[speciesKey]) { + flipped[speciesKey] = []; + } + flipped[speciesKey].push(moveKey); + } + } + } + return flipped; +} + +export const speciesTmMoves: SpeciesTmMoves = transposeTmSpecies(); + interface TmPoolTiers { [key: integer]: ModifierTier } diff --git a/src/test/abilities/shields_down.test.ts b/src/test/abilities/shields_down.test.ts index 6ffc28c37ab..ca6d945824e 100644 --- a/src/test/abilities/shields_down.test.ts +++ b/src/test/abilities/shields_down.test.ts @@ -189,4 +189,19 @@ describe("Abilities - SHIELDS DOWN", () => { } ); + test("should not prevent minior from receiving the fainted status effect in trainer battles", async () => { + game.override.enemyMoveset([ Moves.TACKLE ]); + game.override.moveset([ Moves.THUNDERBOLT ]); + game.override.startingLevel(100); + game.override.startingWave(5); + game.override.enemySpecies(Species.MINIOR); + await game.classicMode.startBattle([ Species.REGIELEKI ]); + const minior = game.scene.getEnemyPokemon()!; + + game.move.select(Moves.THUNDERBOLT); + await game.toNextTurn(); + expect(minior.isFainted()).toBe(true); + expect(minior.status?.effect).toBe(StatusEffect.FAINT); + }); + });