Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Sparkling Aria's interaction with Shield Dust #10882

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion data/abilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4143,7 +4143,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",
Expand Down
2 changes: 1 addition & 1 deletion data/items.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
9 changes: 7 additions & 2 deletions data/mods/fullpotential/scripts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,14 @@ export const Scripts: ModdedBattleScriptsData = {
}
}

const moveHit = target.getMoveHitData(move);
moveHit.successful = true;
if (move.ohko) return target.maxhp;
if (move.damageCallback) return move.damageCallback.call(this.battle, source, target);
if (move.damageCallback) {
const damageCallabackResult = move.damageCallback.call(this.battle, source, target);
moveHit.successful = damageCallabackResult !== false && damageCallabackResult !== null;
return damageCallabackResult;
}
if (move.damage === 'level') {
return source.level;
} else if (move.damage) {
Expand Down Expand Up @@ -50,7 +56,6 @@ export const Scripts: ModdedBattleScriptsData = {
}
}

const moveHit = target.getMoveHitData(move);
moveHit.crit = move.willCrit || false;
if (move.willCrit === undefined) {
if (critRatio) {
Expand Down
9 changes: 7 additions & 2 deletions data/mods/gen1/scripts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -757,14 +757,18 @@ export const Scripts: ModdedBattleScriptsData = {
}
}

const moveHit = target.getMoveHitData(move);
moveHit.successful = true;
// Is it an OHKO move?
if (move.ohko) {
return 65535;
}

// We edit the damage through move's damage callback if necessary.
if (move.damageCallback) {
return move.damageCallback.call(this.battle, source, target);
const damageCallabackResult = move.damageCallback.call(this.battle, source, target);
moveHit.successful = damageCallabackResult !== false && damageCallabackResult !== null;
return damageCallabackResult;
}

// We take damage from damage=level moves (seismic toss).
Expand Down Expand Up @@ -835,7 +839,7 @@ export const Scripts: ModdedBattleScriptsData = {
isCrit = this.battle.randomChance(critChance, 256);
}
}
if (isCrit) target.getMoveHitData(move).crit = true;
if (isCrit) moveHit.crit = true;

// Happens after crit calculation.
if (basePower) {
Expand Down Expand Up @@ -940,6 +944,7 @@ export const Scripts: ModdedBattleScriptsData = {
}
}
const totalTypeMod = target.runEffectiveness(move);
moveHit.typeMod = totalTypeMod;
if (totalTypeMod > 0) {
if (!suppressMessages) this.battle.add('-supereffective', target);
}
Expand Down
9 changes: 7 additions & 2 deletions data/mods/gen1stadium/scripts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -555,14 +555,18 @@ export const Scripts: ModdedBattleScriptsData = {
}
}

const moveHit = target.getMoveHitData(move);
moveHit.successful = true;
// Is it an OHKO move?
if (move.ohko) {
return 65535;
}

// We edit the damage through move's damage callback if necessary.
if (move.damageCallback) {
return move.damageCallback.call(this.battle, source, target);
const damageCallabackResult = move.damageCallback.call(this.battle, source, target);
moveHit.successful = damageCallabackResult !== false && damageCallabackResult !== null;
return damageCallabackResult;
}

// We take damage from damage=level moves (seismic toss).
Expand Down Expand Up @@ -643,7 +647,7 @@ export const Scripts: ModdedBattleScriptsData = {
}
// There is a critical hit.
if (isCrit && this.battle.runEvent('CriticalHit', target, null, move)) {
target.getMoveHitData(move).crit = true;
moveHit.crit = true;
}

// Happens after crit calculation.
Expand Down Expand Up @@ -740,6 +744,7 @@ export const Scripts: ModdedBattleScriptsData = {
}
}
const totalTypeMod = target.runEffectiveness(move);
moveHit.typeMod = totalTypeMod;
if (totalTypeMod > 0) {
if (!suppressMessages) this.battle.add('-supereffective', target);
}
Expand Down
9 changes: 7 additions & 2 deletions data/mods/gen2/scripts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -503,14 +503,18 @@ export const Scripts: ModdedBattleScriptsData = {
}
}

const moveHit = target.getMoveHitData(move);
moveHit.successful = true;
// Is it an OHKO move?
if (move.ohko) {
return target.maxhp;
}

// We edit the damage through move's damage callback
if (move.damageCallback) {
return move.damageCallback.call(this.battle, source, target);
const damageCallabackResult = move.damageCallback.call(this.battle, source, target);
moveHit.successful = damageCallabackResult !== false && damageCallabackResult !== null;
return damageCallabackResult;
}

// We take damage from damage=level moves
Expand Down Expand Up @@ -554,7 +558,7 @@ export const Scripts: ModdedBattleScriptsData = {
}

if (isCrit && this.battle.runEvent('CriticalHit', target, null, move)) {
target.getMoveHitData(move).crit = true;
moveHit.crit = true;
}

// Happens after crit calculation
Expand Down Expand Up @@ -689,6 +693,7 @@ export const Scripts: ModdedBattleScriptsData = {

// Type effectiveness
const totalTypeMod = target.runEffectiveness(move);
moveHit.typeMod = totalTypeMod;
// Super effective attack
if (totalTypeMod > 0) {
if (!suppressMessages) this.battle.add('-supereffective', target);
Expand Down
9 changes: 7 additions & 2 deletions data/mods/gen2doubles/scripts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,18 @@ export const Scripts: ModdedBattleScriptsData = {
}
}

const moveHit = target.getMoveHitData(move);
moveHit.successful = true;
// Is it an OHKO move?
if (move.ohko) {
return target.maxhp;
}

// We edit the damage through move's damage callback
if (move.damageCallback) {
return move.damageCallback.call(this.battle, source, target);
const damageCallabackResult = move.damageCallback.call(this.battle, source, target);
moveHit.successful = damageCallabackResult !== false && damageCallabackResult !== null;
return damageCallabackResult;
}

// We take damage from damage=level moves
Expand Down Expand Up @@ -140,7 +144,7 @@ export const Scripts: ModdedBattleScriptsData = {
}

if (isCrit && this.battle.runEvent('CriticalHit', target, null, move)) {
target.getMoveHitData(move).crit = true;
moveHit.crit = true;
}

// Happens after crit calculation
Expand Down Expand Up @@ -275,6 +279,7 @@ export const Scripts: ModdedBattleScriptsData = {

// Type effectiveness
const totalTypeMod = target.runEffectiveness(move);
moveHit.typeMod = totalTypeMod;
// Super effective attack
if (totalTypeMod > 0) {
if (!suppressMessages) this.battle.add('-supereffective', target);
Expand Down
9 changes: 7 additions & 2 deletions data/mods/gen2stadium2/scripts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -264,14 +264,18 @@ export const Scripts: ModdedBattleScriptsData = {
}
}

const moveHit = target.getMoveHitData(move);
moveHit.successful = true;
// Is it an OHKO move?
if (move.ohko) {
return target.maxhp;
}

// We edit the damage through move's damage callback
if (move.damageCallback) {
return move.damageCallback.call(this.battle, source, target);
const damageCallabackResult = move.damageCallback.call(this.battle, source, target);
moveHit.successful = damageCallabackResult !== false && damageCallabackResult !== null;
return damageCallabackResult;
}

// We take damage from damage=level moves
Expand Down Expand Up @@ -315,7 +319,7 @@ export const Scripts: ModdedBattleScriptsData = {
}

if (isCrit && this.battle.runEvent('CriticalHit', target, null, move)) {
target.getMoveHitData(move).crit = true;
moveHit.crit = true;
}

// Happens after crit calculation
Expand Down Expand Up @@ -430,6 +434,7 @@ export const Scripts: ModdedBattleScriptsData = {

// Type effectiveness
const totalTypeMod = target.runEffectiveness(move);
moveHit.typeMod = totalTypeMod;
// Super effective attack
if (totalTypeMod > 0) {
if (!suppressMessages) this.battle.add('-supereffective', target);
Expand Down
2 changes: 1 addition & 1 deletion data/mods/gen9ssb/abilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1867,7 +1867,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: {},
},
Expand Down
6 changes: 4 additions & 2 deletions data/moves.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18032,13 +18032,15 @@ 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) {
if (move.hasSheerForce) return;
const numberTargets = move.moveHitData ? Object.values(move.moveHitData).filter(m => m.successful).length : 0;
for (const pokemon of this.getAllActive()) {
if (pokemon !== source && pokemon.removeVolatile('sparklingaria') && pokemon.status === 'brn' && !source.fainted) {
if (pokemon !== source && (pokemon.removeVolatile('sparklingaria') || numberTargets > 1) && pokemon.status === 'brn' &&
!source.fainted) {
pokemon.cureStatus();
}
}
Expand Down
11 changes: 8 additions & 3 deletions sim/battle-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1576,7 +1576,7 @@ export class BattleActions {
* Normal PS return value rules apply:
* undefined = success, null = silent failure, false = loud failure
*/
getDamage(
getDamage(
source: Pokemon, target: Pokemon, move: string | number | ActiveMove,
suppressMessages = false
): number | undefined | null | false {
Expand All @@ -1599,8 +1599,14 @@ export class BattleActions {
}
}

const moveHit = target.getMoveHitData(move);
moveHit.successful = true;
if (move.ohko) return target.maxhp;
if (move.damageCallback) return move.damageCallback.call(this.battle, source, target);
if (move.damageCallback) {
const damageCallabackResult = move.damageCallback.call(this.battle, source, target);
moveHit.successful = damageCallabackResult !== false && damageCallabackResult !== null;
return damageCallabackResult;
}
if (move.damage === 'level') {
return source.level;
} else if (move.damage) {
Expand Down Expand Up @@ -1630,7 +1636,6 @@ export class BattleActions {
}
}

const moveHit = target.getMoveHitData(move);
moveHit.crit = move.willCrit || false;
if (move.willCrit === undefined) {
if (critRatio) {
Expand Down
7 changes: 2 additions & 5 deletions sim/dex-moves.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -296,6 +291,8 @@ export interface Move extends Readonly<BasicEffect & MoveData> {

interface MoveHitData {
[targetSlotid: string]: {
/** Did this move do damage to the target? */
successful: boolean,
/** Did this move crit against the target? */
crit: boolean,
/** The type effectiveness of this move against the target */
Expand Down
1 change: 1 addition & 0 deletions sim/pokemon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -670,6 +670,7 @@ export class Pokemon {
if (!move.moveHitData) move.moveHitData = {};
const slot = this.getSlot();
return move.moveHitData[slot] || (move.moveHitData[slot] = {
successful: false,
crit: false,
typeMod: 0,
zBrokeProtect: false,
Expand Down
20 changes: 6 additions & 14 deletions test/sim/abilities/shielddust.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,27 +72,19 @@ describe('Shield Dust', function () {
assert.statStage(battle.p2.active[0], 'spa', -1);
});

it.skip(`should only prevent Sparkling Aria from curing burn if there is only one target`, function () {
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`, function () {
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`);
});
});
2 changes: 1 addition & 1 deletion test/sim/moves/roost.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ describe('Roost', function () {
assert.equal(battle.p2.active[0].hp, battle.p2.active[0].maxhp);
});

it('should suppress user\'s current Flying type if succesful', function () {
it('should suppress user\'s current Flying type if successful', function () {
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']}]});
Expand Down