diff --git a/src/data/ability.ts b/src/data/ability.ts index bfc608dc7e0..ed6e72e4555 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -9,7 +9,7 @@ import { BattlerTag } from "./battler-tags"; import { BattlerTagType } from "./enums/battler-tag-type"; import { StatusEffect, getStatusEffectDescriptor, getStatusEffectHealText } from "./status-effect"; import { Gender } from "./gender"; -import Move, { AttackMove, MoveCategory, MoveFlags, MoveTarget, RecoilAttr, StatusMoveTypeImmunityAttr, FlinchAttr, OneHitKOAttr, HitHealAttr, StrengthSapHealAttr, allMoves } from "./move"; +import Move, { AttackMove, MoveCategory, MoveFlags, MoveTarget, RecoilAttr, StatusMoveTypeImmunityAttr, FlinchAttr, OneHitKOAttr, HitHealAttr, StrengthSapHealAttr, allMoves, StatusMove } from "./move"; import { ArenaTagSide, ArenaTrapTag } from "./arena-tag"; import { ArenaTagType } from "./enums/arena-tag-type"; import { Stat } from "./pokemon-stat"; @@ -1640,6 +1640,54 @@ function getAnticipationCondition(): AbAttrCondition { }; } +export class ForewarnAbAttr extends PostSummonAbAttr { + constructor() { + super(true); + } + + applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean { + let maxPowerSeen = 0; + let maxMove = ""; + let movePower = 0; + for (let opponent of pokemon.getOpponents()) { + for (let move of opponent.moveset) { + if (move.getMove() instanceof StatusMove) { + movePower = 1; + } else { + if (move.getMove().hasFlag(MoveFlags.OHKO_Move)) { + movePower = 150; + } else if (move.getMove().id === Moves.COUNTER || move.getMove().id === Moves.MIRROR_COAT || move.getMove().id === Moves.METAL_BURST) { + movePower = 120; + } else if (move.getMove().power === -1) { + movePower = 80; + } else { + movePower = move.getMove().power; + } + } + if (movePower > maxPowerSeen) { + maxPowerSeen = movePower; + maxMove = move.getName(); + } + } + } + pokemon.scene.queueMessage(getPokemonMessage(pokemon, " was forewarned about " + maxMove + "!")); + return true; + } +} + +export class FriskAbAttr extends PostSummonAbAttr { + constructor() { + super(true); + } + + applyPostSummon(pokemon: Pokemon, passive: boolean, args: any[]): boolean { + for (let opponent of pokemon.getOpponents()) { + pokemon.scene.queueMessage(getPokemonMessage(pokemon, " frisked " + opponent.name + "\'s " + opponent.getAbility().name + "!")); + } + return true; + } +} + export class PostWeatherChangeAbAttr extends AbAttr { applyPostWeatherChange(pokemon: Pokemon, passive: boolean, weather: WeatherType, args: any[]): boolean { return false; @@ -2669,7 +2717,8 @@ export function initAbilities() { .bypassFaint(), new Ability(Abilities.ANTICIPATION, "Anticipation", "The Pokémon can sense an opposing Pokémon's dangerous moves.", 4) .conditionalAttr(getAnticipationCondition(), PostSummonMessageAbAttr, (pokemon: Pokemon) => getPokemonMessage(pokemon, ' shuddered!')), - new Ability(Abilities.FOREWARN, "Forewarn (N)", "When it enters a battle, the Pokémon can tell one of the moves an opposing Pokémon has.", 4), + new Ability(Abilities.FOREWARN, "Forewarn", "When it enters a battle, the Pokémon can tell one of the moves an opposing Pokémon has.", 4) + .attr(ForewarnAbAttr), new Ability(Abilities.UNAWARE, "Unaware", "When attacking, the Pokémon ignores the target Pokémon's stat changes.", 4) .attr(IgnoreOpponentStatChangesAbAttr) .ignorable(), @@ -2695,7 +2744,8 @@ export function initAbilities() { .attr(PostSummonWeatherChangeAbAttr, WeatherType.SNOW) .attr(PostBiomeChangeWeatherChangeAbAttr, WeatherType.SNOW), new Ability(Abilities.HONEY_GATHER, "Honey Gather (N)", "The Pokémon may gather Honey after a battle.", 4), - new Ability(Abilities.FRISK, "Frisk (N)", "When it enters a battle, the Pokémon can check an opposing Pokémon's held item.", 4), + new Ability(Abilities.FRISK, "Frisk", "When it enters a battle, the Pokémon can check an opposing Pokémon's ability.", 4) + .attr(FriskAbAttr), new Ability(Abilities.RECKLESS, "Reckless", "Powers up moves that have recoil damage.", 4) .attr(MovePowerBoostAbAttr, (user, target, move) => move.getAttrs(RecoilAttr).length && move.id !== Moves.STRUGGLE, 1.2), new Ability(Abilities.MULTITYPE, "Multitype (N)", "Changes the Pokémon's type to match the Plate or Z-Crystal it holds.", 4) diff --git a/src/data/battler-tags.ts b/src/data/battler-tags.ts index 25ff41ec3e2..723ea775967 100644 --- a/src/data/battler-tags.ts +++ b/src/data/battler-tags.ts @@ -934,6 +934,19 @@ export class HideSpriteTag extends BattlerTag { } } +export class TypeImmuneTag extends BattlerTag { + public immuneType: Type; + constructor(tagType: BattlerTagType, sourceMove: Moves, immuneType: Type, length: number) { + super(tagType, BattlerTagLapseType.TURN_END, 1, sourceMove); + } +} + +export class MagnetRisenTag extends TypeImmuneTag { + constructor(tagType: BattlerTagType, sourceMove: Moves) { + super(tagType, sourceMove, Type.GROUND, 5); + } +} + export class TypeBoostTag extends BattlerTag { public boostedType: Type; public boostValue: number; @@ -1155,6 +1168,8 @@ export function getBattlerTag(tagType: BattlerTagType, turnCount: integer, sourc return new CursedTag(sourceId); case BattlerTagType.CHARGED: return new TypeBoostTag(tagType, sourceMove, Type.ELECTRIC, 2, true); + case BattlerTagType.MAGNET_RISEN: + return new MagnetRisenTag(tagType, sourceMove); case BattlerTagType.NONE: default: return new BattlerTag(tagType, BattlerTagLapseType.CUSTOM, turnCount, sourceMove, sourceId); diff --git a/src/data/enums/battler-tag-type.ts b/src/data/enums/battler-tag-type.ts index 9c740ef4629..fa83ad1468c 100644 --- a/src/data/enums/battler-tag-type.ts +++ b/src/data/enums/battler-tag-type.ts @@ -51,5 +51,6 @@ export enum BattlerTagType { SALT_CURED = "SALT_CURED", CURSED = "CURSED", CHARGED = "CHARGED", - GROUNDED = "GROUNDED" + GROUNDED = "GROUNDED", + MAGNET_RISEN = "MAGNET_RISEN" }