This commit is contained in:
André Bastos Dias 2026-06-02 21:52:50 -05:00 committed by GitHub
commit 10329210df
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 42 additions and 10 deletions

View File

@ -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,

View File

@ -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,
},

View File

@ -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",
},

View File

@ -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;

View File

@ -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

View File

@ -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<BasicEffect & Move
* e.g. Electro Shot and Order Up.
*/
readonly hasSheerForceBoost: boolean;
/**
* Immune to Shield Dust and Covert Cloak if the move hits multiple targets
*/
readonly dustproof: boolean;
/**
* Move priority. Higher priorities go before lower priorities,
* trumping the Speed stat.
@ -488,6 +494,7 @@ export class DataMove extends BasicEffect implements Readonly<BasicEffect & Move
this.secondary = data.secondary || undefined;
this.secondaries = data.secondaries || (this.secondary && [this.secondary]) || undefined;
this.hasSheerForceBoost = data.hasSheerForceBoost || false;
this.dustproof = data.dustproof;
this.priority = Number(data.priority) || 0;
this.category = data.category!;
this.overrideOffensiveStat = data.overrideOffensiveStat || undefined;

View File

@ -77,4 +77,15 @@ describe('Sheer Force', () => {
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]);
});
});