diff --git a/src/data/ability.ts b/src/data/ability.ts index 1ba2a8c979a..ab027e3db8d 100644 --- a/src/data/ability.ts +++ b/src/data/ability.ts @@ -202,6 +202,25 @@ export class PreDefendAbAttr extends AbAttr { } } +export class PreDefendFormChangeAbAttr extends PreDefendAbAttr { + private formFunc: (p: Pokemon) => integer; + + constructor(formFunc: ((p: Pokemon) => integer)) { + super(true); + + this.formFunc = formFunc; + } + + applyPreDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, cancelled: Utils.BooleanHolder, args: any[]): boolean { + const formIndex = this.formFunc(pokemon); + if (formIndex !== pokemon.formIndex) { + pokemon.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false); + return true; + } + + return false; + } +} export class PreDefendFullHpEndureAbAttr extends PreDefendAbAttr { applyPreDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, cancelled: Utils.BooleanHolder, args: any[]): boolean { if (pokemon.getHpRatio() < 1 || (args[0] as Utils.NumberHolder).value < pokemon.hp) @@ -261,14 +280,14 @@ export class ReceivedTypeDamageMultiplierAbAttr extends ReceivedMoveDamageMultip } } -export class SetMovePowerToOneAbAttr extends ReceivedMoveDamageMultiplierAbAttr { +export class PreDefendMovePowerToOneAbAttr extends ReceivedMoveDamageMultiplierAbAttr { constructor(condition: PokemonDefendCondition) { super(condition, 1); } applyPreDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, cancelled: Utils.BooleanHolder, args: any[]): boolean { if (this.condition(pokemon, attacker, move.getMove())) { - (args[0] as Utils.NumberHolder).value = 0.001; + (args[0] as Utils.NumberHolder).value = 1; return true; } @@ -403,12 +422,9 @@ export class PostDefendAbAttr extends AbAttr { export class PostDefendDisguiseAbAttr extends PostDefendAbAttr { - constructor(damageRatio?: number) { - super(true); - } - applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean { if (pokemon.formIndex == 0 && pokemon.battleData.hitCount != 0 && (move.getMove().category == MoveCategory.SPECIAL || move.getMove().category == MoveCategory.PHYSICAL)) { + const recoilDamage = Math.ceil((pokemon.getMaxHp() / 8) - attacker.turnData.damageDealt); if (!recoilDamage) return false; @@ -421,6 +437,26 @@ export class PostDefendDisguiseAbAttr extends PostDefendAbAttr { } } +export class PostDefendFormChangeAbAttr extends PostDefendAbAttr { + private formFunc: (p: Pokemon) => integer; + + constructor(formFunc: ((p: Pokemon) => integer)) { + super(true); + + this.formFunc = formFunc; + } + + applyPostDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, hitResult: HitResult, args: any[]): boolean { + const formIndex = this.formFunc(pokemon); + if (formIndex !== pokemon.formIndex) { + pokemon.scene.triggerPokemonFormChange(pokemon, SpeciesFormChangeManualTrigger, false); + return true; + } + + return false; + } +} + export class FieldPriorityMoveImmunityAbAttr extends PreDefendAbAttr { applyPreDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, cancelled: Utils.BooleanHolder, args: any[]): boolean { const attackPriority = new Utils.IntegerHolder(move.getMove().priority); @@ -477,7 +513,7 @@ export class MoveImmunityStatChangeAbAttr extends MoveImmunityAbAttr { applyPreDefend(pokemon: Pokemon, passive: boolean, attacker: Pokemon, move: PokemonMove, cancelled: Utils.BooleanHolder, args: any[]): boolean { const ret = super.applyPreDefend(pokemon, passive, attacker, move, cancelled, args) if (ret) { - pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [ this.stat ], this.levels)); + pokemon.scene.unshiftPhase(new StatChangePhase(pokemon.scene, pokemon.getBattlerIndex(), true, [this.stat], this.levels)); } return ret; @@ -2472,7 +2508,7 @@ export function initAbilities() { .attr(BattleStatMultiplierAbAttr, BattleStat.SPATK, 1.5) .condition(getWeatherCondition(WeatherType.SUNNY, WeatherType.HARSH_SUN)), new Ability(Abilities.QUICK_FEET, "Quick Feet", "Boosts the Speed stat if the Pokémon has a status condition.", 4) - .conditionalAttr(pokemon => pokemon.status.effect === StatusEffect.PARALYSIS, BattleStatMultiplierAbAttr, BattleStat.SPD, 2) + .conditionalAttr(pokemon => pokemon.status ? pokemon.status.effect === StatusEffect.PARALYSIS : false, BattleStatMultiplierAbAttr, BattleStat.SPD, 2) .conditionalAttr(pokemon => !!pokemon.status, BattleStatMultiplierAbAttr, BattleStat.SPD, 1.5), new Ability(Abilities.NORMALIZE, "Normalize", "All the Pokémon's moves become Normal type. The power of those moves is boosted a little.", 4) .attr(MoveTypeChangeAttr, Type.NORMAL, 1.2, (user, target, move) => move.id !== Moves.HIDDEN_POWER && move.id !== Moves.WEATHER_BALL && @@ -2749,8 +2785,11 @@ export function initAbilities() { .attr(UnswappableAbilityAbAttr) .attr(UnsuppressableAbilityAbAttr), new Ability(Abilities.DISGUISE, "Disguise (P)", "Once per battle, the shroud that covers the Pokémon can protect it from an attack.", 7) - .attr(SetMovePowerToOneAbAttr, (target, user, move) => target.formIndex == 0) - .attr(PostTurnFormChangeAbAttr, pokemon => pokemon.battleData.hitCount === 0 ? 0 : 1) + .attr(PreDefendMovePowerToOneAbAttr, (target, user, move) => target.formIndex == 0 && target.getAttackTypeEffectiveness(move.type) > 0) + .attr(PostSummonFormChangeAbAttr, p => p.battleData.hitCount === 0 ? 0 : 1) + .attr(PostBattleInitFormChangeAbAttr, p => p.battleData.hitCount === 0 ? 0 : 1) + .attr(PostDefendFormChangeAbAttr, p => p.battleData.hitCount === 0 ? 0 : 1) + .attr(PreDefendFormChangeAbAttr, p => p.battleData.hitCount === 0 ? 0 : 1) .attr(PostDefendDisguiseAbAttr) .attr(UncopiableAbilityAbAttr) .attr(UnswappableAbilityAbAttr) @@ -3033,4 +3072,4 @@ export function initAbilities() { .attr(UncopiableAbilityAbAttr) .attr(UnswappableAbilityAbAttr) ); -} +} \ No newline at end of file