mirror of
https://github.com/smogon/pokemon-showdown.git
synced 2026-03-21 17:25:10 -05:00
Fix Sparkling Aria's interaction with Shield Dust (#10882)
Some checks are pending
Node.js CI / build (18.x) (push) Waiting to run
Some checks are pending
Node.js CI / build (18.x) (push) Waiting to run
This commit is contained in:
parent
c273081062
commit
6b3d0eefbd
|
|
@ -2428,16 +2428,21 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
},
|
||||
magician: {
|
||||
onAfterMoveSecondarySelf(source, target, move) {
|
||||
if (!move || !target || source.switchFlag === true) return;
|
||||
if (target !== source && move.category !== 'Status') {
|
||||
if (source.item || source.volatiles['gem'] || move.id === 'fling') return;
|
||||
const yourItem = target.takeItem(source);
|
||||
if (!yourItem) return;
|
||||
if (!source.setItem(yourItem)) {
|
||||
target.item = yourItem.id; // bypass setItem so we don't break choicelock or anything
|
||||
if (!move || source.switchFlag === true || !move.hitTargets || source.item || source.volatiles['gem'] ||
|
||||
move.id === 'fling') return;
|
||||
const hitTargets = move.hitTargets;
|
||||
this.speedSort(hitTargets);
|
||||
for (const pokemon of hitTargets) {
|
||||
if (pokemon !== source && move.category !== 'Status') {
|
||||
const yourItem = pokemon.takeItem(source);
|
||||
if (!yourItem) continue;
|
||||
if (!source.setItem(yourItem)) {
|
||||
pokemon.item = yourItem.id; // bypass setItem so we don't break choicelock or anything
|
||||
continue;
|
||||
}
|
||||
this.add('-item', source, yourItem, '[from] ability: Magician', `[of] ${pokemon}`);
|
||||
return;
|
||||
}
|
||||
this.add('-item', source, yourItem, '[from] ability: Magician', `[of] ${target}`);
|
||||
}
|
||||
},
|
||||
flags: {},
|
||||
|
|
@ -4150,7 +4155,7 @@ export const Abilities: import('../sim/dex-abilities').AbilityDataTable = {
|
|||
shielddust: {
|
||||
onModifySecondaries(secondaries) {
|
||||
this.debug('Shield Dust prevent secondary');
|
||||
return secondaries.filter(effect => !!(effect.self || effect.dustproof));
|
||||
return secondaries.filter(effect => !!effect.self);
|
||||
},
|
||||
flags: { breakable: 1 },
|
||||
name: "Shield Dust",
|
||||
|
|
|
|||
|
|
@ -1152,7 +1152,7 @@ export const Items: import('../sim/dex-items').ItemDataTable = {
|
|||
},
|
||||
onModifySecondaries(secondaries) {
|
||||
this.debug('Covert Cloak prevent secondary');
|
||||
return secondaries.filter(effect => !!(effect.self || effect.dustproof));
|
||||
return secondaries.filter(effect => !!effect.self);
|
||||
},
|
||||
num: 1885,
|
||||
gen: 9,
|
||||
|
|
|
|||
|
|
@ -1869,7 +1869,7 @@ export const Abilities: import('../../../sim/dex-abilities').ModdedAbilityDataTa
|
|||
},
|
||||
onModifySecondaries(secondaries) {
|
||||
this.debug('Fancy Scarf prevent secondary');
|
||||
return secondaries.filter(effect => !!(effect.self || effect.dustproof));
|
||||
return secondaries.filter(effect => !!effect.self);
|
||||
},
|
||||
flags: {},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -18044,13 +18044,20 @@ export const Moves: import('../sim/dex-moves').MoveDataTable = {
|
|||
priority: 0,
|
||||
flags: { protect: 1, mirror: 1, sound: 1, bypasssub: 1, metronome: 1 },
|
||||
secondary: {
|
||||
dustproof: true,
|
||||
chance: 100,
|
||||
volatileStatus: 'sparklingaria',
|
||||
},
|
||||
onAfterMove(source, target, move) {
|
||||
for (const pokemon of this.getAllActive()) {
|
||||
if (pokemon !== source && pokemon.removeVolatile('sparklingaria') && pokemon.status === 'brn' && !source.fainted) {
|
||||
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') {
|
||||
pokemon.cureStatus();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -606,6 +606,7 @@ export class BattleActions {
|
|||
}
|
||||
}
|
||||
|
||||
move.hitTargets = targets;
|
||||
const moveResult = !!targets.length;
|
||||
if (!moveResult && !atLeastOneFailure) pokemon.moveThisTurnResult = null;
|
||||
const hitSlot = targets.map(p => p.getSlot());
|
||||
|
|
|
|||
|
|
@ -87,11 +87,6 @@ export interface SecondaryEffect extends HitEffect {
|
|||
chance?: number;
|
||||
/** Used to flag a secondary effect as added by Poison Touch */
|
||||
ability?: Ability;
|
||||
/**
|
||||
* Applies to Sparkling Aria's secondary effect: Affected by
|
||||
* Sheer Force but not Shield Dust.
|
||||
*/
|
||||
dustproof?: boolean;
|
||||
/**
|
||||
* Gen 2 specific mechanics: Bypasses Substitute only on Twineedle,
|
||||
* and allows it to flinch sleeping/frozen targets
|
||||
|
|
@ -317,6 +312,7 @@ export interface ActiveMove extends MutableMove {
|
|||
status?: ID;
|
||||
hit: number;
|
||||
moveHitData?: MoveHitData;
|
||||
hitTargets?: Pokemon[];
|
||||
ability?: Ability;
|
||||
allies?: Pokemon[];
|
||||
auraBooster?: Pokemon;
|
||||
|
|
|
|||
|
|
@ -74,4 +74,18 @@ describe('Magician', () => {
|
|||
battle.makeChoices();
|
||||
assert.false.holdsItem(battle.p1.active[0], 'Klefki should not have stolen Weakness Policy.');
|
||||
});
|
||||
|
||||
it(`should steal the item from the faster opponent hit`, () => {
|
||||
battle = common.createBattle({ gameType: 'doubles' }, [[
|
||||
{ species: "Hoopa", ability: 'magician', moves: ['expandingforce'] },
|
||||
{ species: "Tapu Lele", ability: 'psychicsurge', moves: ['sleeptalk'] },
|
||||
], [
|
||||
{ species: "Shuckle", item: 'tr68', moves: ['sleeptalk'] },
|
||||
{ species: "Zapdos", item: 'tr69', moves: ['sleeptalk'] }],
|
||||
]);
|
||||
battle.makeChoices();
|
||||
assert.equal(battle.p1.active[0].item, 'tr69');
|
||||
assert.equal(battle.p2.active[0].item, 'tr68');
|
||||
assert.equal(battle.p2.active[1].item, '');
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -72,27 +72,19 @@ describe('Shield Dust', () => {
|
|||
assert.statStage(battle.p2.active[0], 'spa', -1);
|
||||
});
|
||||
|
||||
it.skip(`should only prevent Sparkling Aria from curing burn if there is only one target`, () => {
|
||||
battle = common.createBattle([[
|
||||
{ species: 'wynaut', ability: 'noguard', moves: ['willowisp', 'sparklingaria'] },
|
||||
], [
|
||||
{ species: 'dustox', ability: 'shielddust', moves: ['sleeptalk'] },
|
||||
]]);
|
||||
battle.makeChoices('move willowisp', 'auto');
|
||||
battle.makeChoices('move sparklingaria', 'auto');
|
||||
|
||||
assert.equal(battle.p2.active[0].status, 'brn', `Shield Dust should prevent cured burn if it's the only target`);
|
||||
|
||||
it(`should only prevent Sparkling Aria from curing burn if there is only one target`, () => {
|
||||
battle = common.createBattle({ gameType: 'doubles' }, [[
|
||||
{ species: 'wynaut', ability: 'noguard', moves: ['willowisp', 'sparklingaria'] },
|
||||
{ species: 'diglett', moves: ['sleeptalk'] },
|
||||
{ species: 'diglett', moves: ['sleeptalk', 'protect'] },
|
||||
], [
|
||||
{ species: 'dustox', ability: 'shielddust', moves: ['sleeptalk'] },
|
||||
{ species: 'magikarp', moves: ['sleeptalk'] },
|
||||
{ species: 'magikarp', moves: ['sleeptalk', 'protect'] },
|
||||
]]);
|
||||
battle.makeChoices('move willowisp 1, move sleeptalk', 'auto');
|
||||
battle.makeChoices('move sparklingaria, move sleeptalk', 'auto');
|
||||
battle.makeChoices('move sparklingaria, move protect', 'move sleeptalk, move protect');
|
||||
assert.equal(battle.p2.active[0].status, 'brn', `Shield Dust should prevent cured burn if it's the only target`);
|
||||
|
||||
battle.makeChoices('move sparklingaria, move sleeptalk', 'auto');
|
||||
assert.equal(battle.p2.active[0].status, '', `Shield Dust should not prevent cured burn if it's one of many targets`);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ describe('Roost', () => {
|
|||
assert.equal(battle.p2.active[0].hp, battle.p2.active[0].maxhp);
|
||||
});
|
||||
|
||||
it('should suppress user\'s current Flying type if succesful', () => {
|
||||
it('should suppress user\'s current Flying type if successful', () => {
|
||||
battle = common.createBattle();
|
||||
battle.setPlayer('p1', { team: [{ species: "Aggron", item: 'leftovers', ability: 'sturdy', moves: ['mudslap', 'hiddenpowergrass'] }] });
|
||||
battle.setPlayer('p2', { team: [{ species: "Aerodactyl", item: 'focussash', ability: 'wonderguard', moves: ['roost', 'doubleedge'] }] });
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user