Skip to content

Commit

Permalink
Add support for moves breaking screens (#649)
Browse files Browse the repository at this point in the history
In these examples, Zen Headbutt's Base Power is increased to match that of Psychic Fangs.

Before:
`0 Atk Mew Zen Headbutt vs. 0 HP / 0 Def Mew through Reflect: 23-27 (6.7 - 7.9%) -- possibly the worst move ever`
`0 Atk Mew Psychic Fangs vs. 0 HP / 0 Def Mew through Reflect: 23-27 (6.7 - 7.9%) -- possibly the worst move ever`

After:
`0 Atk Mew Zen Headbutt vs. 0 HP / 0 Def Mew through Reflect: 23-27 (6.7 - 7.9%) -- possibly the worst move ever`
`0 Atk Mew Psychic Fangs vs. 0 HP / 0 Def Mew: 46-54 (13.4 - 15.8%) -- possible 7HKO`

Fixes https://www.smogon.com/forums/posts/10281815
  • Loading branch information
shrianshChari authored Oct 6, 2024
1 parent 0f40891 commit 27588bd
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 0 deletions.
3 changes: 3 additions & 0 deletions calc/src/mechanics/gen3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ export function calculateADV(
desc.weather = field.weather;
desc.moveType = move.type;
desc.moveBP = move.bp;
} else if (move.named('Brick Break')) {
field.defenderSide.isReflect = false;
field.defenderSide.isLightScreen = false;
}

const typeEffectivenessPrecedenceRules = [
Expand Down
3 changes: 3 additions & 0 deletions calc/src/mechanics/gen4.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ export function calculateDPP(
desc.attackerItem = attacker.item;
desc.moveBP = move.bp;
desc.moveType = move.type;
} else if (move.named('Brick Break')) {
field.defenderSide.isReflect = false;
field.defenderSide.isLightScreen = false;
}

if (attacker.hasAbility('Normalize') && !move.named('Struggle')) {
Expand Down
3 changes: 3 additions & 0 deletions calc/src/mechanics/gen56.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,9 @@ export function calculateBWXY(
: field.hasTerrain('Misty') ? 'Fairy'
: 'Normal';
}
} else if (move.named('Brick Break')) {
field.defenderSide.isReflect = false;
field.defenderSide.isLightScreen = false;
}

let hasAteAbilityTypeChange = false;
Expand Down
8 changes: 8 additions & 0 deletions calc/src/mechanics/gen789.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,10 @@ export function calculateSMSSSV(
} else if (attacker.named('Tauros-Paldea-Aqua')) {
type = 'Water';
}

field.defenderSide.isReflect = false;
field.defenderSide.isLightScreen = false;
field.defenderSide.isAuroraVeil = false;
} else if (move.named('Ivy Cudgel')) {
if (attacker.name.includes('Ogerpon-Cornerstone')) {
type = 'Rock';
Expand All @@ -286,6 +290,10 @@ export function calculateSMSSSV(
) {
move.target = 'allAdjacentFoes';
type = 'Stellar';
} else if (move.named('Brick Break', 'Psychic Fangs')) {
field.defenderSide.isReflect = false;
field.defenderSide.isLightScreen = false;
field.defenderSide.isAuroraVeil = false;
}

let hasAteAbilityTypeChange = false;
Expand Down
59 changes: 59 additions & 0 deletions calc/src/test/calc.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1452,5 +1452,64 @@ describe('calc', () => {
});
});
});
describe('Some moves should break screens before doing damage', () => {
inGens(3, 9, ({calculate, Pokemon, Move, Field}) => {
test('Brick Break should break screens', () => {
const pokemon = Pokemon('Mew');

const brickBreak = Move('Brick Break');
const otherMove = Move('Vital Throw', {overrides: {basePower: 75}});

const field = Field({defenderSide: {isReflect: true}});

const brickBreakResult = calculate(pokemon, pokemon, brickBreak, field);
expect(brickBreakResult.field.defenderSide.isReflect).toBe(false);

const otherMoveResult = calculate(pokemon, pokemon, otherMove, field);
expect(otherMoveResult.field.defenderSide.isReflect).toBe(true);

expect(brickBreakResult.range()[0]).toBeGreaterThan(otherMoveResult.range()[0]);
expect(brickBreakResult.range()[1]).toBeGreaterThan(otherMoveResult.range()[1]);
});
});
inGens(7, 9, ({calculate, Pokemon, Move, Field}) => {
test('Psychic Fangs should break screens', () => {
const pokemon = Pokemon('Mew');

const psychicFangs = Move('Psychic Fangs');
const otherMove = Move('Zen Headbutt', {overrides: {basePower: 75}});

const field = Field({defenderSide: {isReflect: true}});

const psychicFangsResult = calculate(pokemon, pokemon, psychicFangs, field);
expect(psychicFangsResult.field.defenderSide.isReflect).toBe(false);

const otherMoveResult = calculate(pokemon, pokemon, otherMove, field);
expect(otherMoveResult.field.defenderSide.isReflect).toBe(true);

expect(psychicFangsResult.range()[0]).toBeGreaterThan(otherMoveResult.range()[0]);
expect(psychicFangsResult.range()[1]).toBeGreaterThan(otherMoveResult.range()[1]);
});
});
inGen(9, ({calculate, Pokemon, Move, Field}) => {
test('Raging Bull should break screens', () => {
const pokemon = Pokemon('Tauros-Paldea-Aqua');

const ragingBull = Move('Raging Bull');
const otherMove = Move('Waterfall', {overrides: {basePower: 90}});

const field = Field({defenderSide: {isReflect: true}});

const ragingBullResult = calculate(pokemon, pokemon, ragingBull, field);
expect(ragingBullResult.field.defenderSide.isReflect).toBe(false);

const otherMoveResult = calculate(pokemon, pokemon, otherMove, field);
expect(otherMoveResult.field.defenderSide.isReflect).toBe(true);

expect(ragingBullResult.range()[0]).toBeGreaterThan(otherMoveResult.range()[0]);
expect(ragingBullResult.range()[1]).toBeGreaterThan(otherMoveResult.range()[1]);
});
});
});
});
});

0 comments on commit 27588bd

Please sign in to comment.