diff --git a/data/abilities.ts b/data/abilities.ts index 2bbe4b3de8..3249af4695 100644 --- a/data/abilities.ts +++ b/data/abilities.ts @@ -4169,6 +4169,10 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = { onBasePower(basePower, pokemon, target, move) { if (move.hasSheerForce || move.hasSheerForceBoost) return this.chainModify([5325, 4096]); }, + onModifyMovePhase2(move, source, target) { + ((this.effect as any).onModifyMove as (m: ActiveMove, p: Pokemon, p2: Pokemon) => void) + .call(this, move, source, target!); + }, flags: {}, name: "Sheer Force", rating: 3.5, @@ -4186,6 +4190,9 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = { this.debug('Shield Dust prevent secondary'); return secondaries.filter(effect => !!effect.self); }, + onSourceModifyMovePhase2(move) { + if (move.numberTargets === 1) move.dustproof = false; + }, flags: { breakable: 1 }, name: "Shield Dust", rating: 2, diff --git a/data/items.ts b/data/items.ts index 024f5bda0a..b4a3da5b3b 100644 --- a/data/items.ts +++ b/data/items.ts @@ -1208,6 +1208,9 @@ export const Items: import('../sim/dex-items').ItemDataTable = { this.debug('Covert Cloak prevent secondary'); return secondaries.filter(effect => !!effect.self); }, + onSourceModifyMovePhase2(move) { + if (move.numberTargets === 1) move.dustproof = false; + }, num: 1885, gen: 9, }, diff --git a/data/moves.ts b/data/moves.ts index 67fc257f2d..c8b32650fe 100644 --- a/data/moves.ts +++ b/data/moves.ts @@ -17373,21 +17373,15 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = { volatileStatus: 'sparklingaria', }, onAfterMove(source, target, move) { - if (source.fainted || !move.hitTargets || move.hasSheerForce) { - // make sure the volatiles are cleared - for (const pokemon of this.getAllActive()) delete pokemon.volatiles['sparklingaria']; - return; - } - const numberTargets = move.hitTargets.length; - for (const pokemon of move.hitTargets) { - // bypasses Shield Dust when hitting multiple targets - if (pokemon !== source && pokemon.isActive && (pokemon.removeVolatile('sparklingaria') || numberTargets > 1) && - pokemon.status === 'brn') { + if (source.fainted) return; + for (const pokemon of this.getAllActive()) { + if ((pokemon.removeVolatile('sparklingaria') || move.dustproof) && pokemon.status === 'brn') { pokemon.cureStatus(); } } }, target: "allAdjacent", + dustproof: true, type: "Water", contestType: "Tough", }, diff --git a/sim/battle-actions.ts b/sim/battle-actions.ts index 66fd617e6d..91e3a3a15c 100644 --- a/sim/battle-actions.ts +++ b/sim/battle-actions.ts @@ -804,6 +804,10 @@ export class BattleActions { return undefined; } afterMoveSecondaryEvent(targets: Pokemon[], pokemon: Pokemon, move: ActiveMove) { + for (const target of targets) { + this.battle.runEvent('ModifyMovePhase2', pokemon, target, move, move); + } + // console.log(`${targets}, ${pokemon}, ${move}`) if (!(move.hasSheerForce && pokemon.hasAbility('sheerforce'))) { this.battle.singleEvent('AfterMoveSecondary', move, null, targets[0], pokemon, move); @@ -1109,6 +1113,7 @@ export class BattleActions { for (const i of targets.keys()) { if (!damage[i] && damage[i] !== 0) targets[i] = false; } + move.numberTargets = damage.filter(val => typeof val === 'number').length; // steps 4 and 5 can mess with this.battle.activeTarget, which needs to be preserved for Dancer const activeTarget = this.battle.activeTarget; diff --git a/sim/dex-conditions.ts b/sim/dex-conditions.ts index 9445d46083..c16bde5691 100644 --- a/sim/dex-conditions.ts +++ b/sim/dex-conditions.ts @@ -66,6 +66,7 @@ export interface EventMethods { onModifyDamage?: CommonHandlers['ModifierSourceMove']; onModifyDef?: CommonHandlers['ModifierMove']; onModifyMove?: MoveEventMethods['onModifyMove']; + onModifyMovePhase2?: MoveEventMethods['onModifyMove']; onModifyPriority?: CommonHandlers['ModifierSourceMove']; onModifySecondaries?: ( this: Battle, secondaries: SecondaryEffect[], target: Pokemon, source: Pokemon, move: ActiveMove @@ -171,6 +172,7 @@ export interface EventMethods { onFoeModifyDamage?: CommonHandlers['ModifierSourceMove']; onFoeModifyDef?: CommonHandlers['ModifierMove']; onFoeModifyMove?: MoveEventMethods['onModifyMove']; + onFoeModifyMovePhase2?: MoveEventMethods['onModifyMove']; onFoeModifyPriority?: CommonHandlers['ModifierSourceMove']; onFoeModifySecondaries?: ( this: Battle, secondaries: SecondaryEffect[], target: Pokemon, source: Pokemon, move: ActiveMove @@ -269,6 +271,7 @@ export interface EventMethods { onSourceModifyDamage?: CommonHandlers['ModifierSourceMove']; onSourceModifyDef?: CommonHandlers['ModifierMove']; onSourceModifyMove?: MoveEventMethods['onModifyMove']; + onSourceModifyMovePhase2?: MoveEventMethods['onModifyMove']; onSourceModifyPriority?: CommonHandlers['ModifierSourceMove']; onSourceModifySecondaries?: ( this: Battle, secondaries: SecondaryEffect[], target: Pokemon, source: Pokemon, move: ActiveMove @@ -371,6 +374,7 @@ export interface EventMethods { onAnyModifyDamage?: CommonHandlers['ModifierSourceMove']; onAnyModifyDef?: CommonHandlers['ModifierMove']; onAnyModifyMove?: MoveEventMethods['onModifyMove']; + onAnyModifyMovePhase2?: MoveEventMethods['onModifyMove']; onAnyModifyPriority?: CommonHandlers['ModifierSourceMove']; onAnyModifySecondaries?: ( this: Battle, secondaries: SecondaryEffect[], target: Pokemon, source: Pokemon, move: ActiveMove @@ -545,6 +549,7 @@ export interface PokemonEventMethods extends EventMethods { onAllyModifyDamage?: CommonHandlers['ModifierSourceMove']; onAllyModifyDef?: CommonHandlers['ModifierMove']; onAllyModifyMove?: MoveEventMethods['onModifyMove']; + onAllyModifyMovePhase2?: MoveEventMethods['onModifyMove']; onAllyModifyPriority?: CommonHandlers['ModifierSourceMove']; onAllyModifySecondaries?: ( this: Battle, secondaries: SecondaryEffect[], target: Pokemon, source: Pokemon, move: ActiveMove diff --git a/sim/dex-moves.ts b/sim/dex-moves.ts index f159dc1155..39acf4f5d7 100644 --- a/sim/dex-moves.ts +++ b/sim/dex-moves.ts @@ -214,6 +214,7 @@ export interface MoveData extends EffectData, MoveEventMethods, HitEffect { * Boosted by Sheer Force without suppressing secondary effects. */ hasSheerForceBoost?: boolean; + dustproof?: boolean; // Hit effect modifiers // -------------------- @@ -316,6 +317,7 @@ export interface ActiveMove extends MutableMove { status?: ID; hit: number; moveHitData?: MoveHitData; + numberTargets?: number; hitTargets?: Pokemon[]; ability?: Ability; allies?: Pokemon[]; @@ -390,6 +392,10 @@ export class DataMove extends BasicEffect implements Readonly { battle.makeChoices('move flamethrower', 'auto'); assert.equal(frozenMon.status, ''); }); + + it('should suppress Life Orb recoil after knocking out a Neutralizing Gas user', () => { + battle = common.createBattle([[ + { species: 'landorus', ability: 'sheerforce', item: 'lifeorb', moves: ['earthpower'] }, + ], [ + { species: 'weezing', ability: 'neutralizinggas', moves: ['sleeptalk'] }, + { species: 'wynaut', ability: 'neutralizinggas', moves: ['sleeptalk'] }, + ]]); + battle.makeChoices(); + assert.fullHP(battle.p1.active[0]); + }); });