Skip to content

Commit

Permalink
Reapply "Ring Target works on all immunities (smogon#646)"
Browse files Browse the repository at this point in the history
This reverts commit c87dd20.
  • Loading branch information
ViZarSmogon committed Dec 16, 2024
1 parent c87dd20 commit 9e56c00
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 17 deletions.
14 changes: 5 additions & 9 deletions calc/src/mechanics/gen56.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,10 +191,13 @@ export function calculateBWXY(
}

const isGhostRevealed = attacker.hasAbility('Scrappy') || field.defenderSide.isForesight;
const isRingTarget = defender.hasItem('Ring Target') && !defender.hasAbility('Klutz');
const type1Effectiveness =
getMoveEffectiveness(gen, move, defender.types[0], isGhostRevealed, field.isGravity);
getMoveEffectiveness(gen, move, defender.types[0], isGhostRevealed, field.isGravity,
isRingTarget);
const type2Effectiveness = defender.types[1]
? getMoveEffectiveness(gen, move, defender.types[1], isGhostRevealed, field.isGravity)
? getMoveEffectiveness(gen, move, defender.types[1], isGhostRevealed, field.isGravity,
isRingTarget)
: 1;
let typeEffectiveness = type1Effectiveness * type2Effectiveness;

Expand All @@ -203,13 +206,6 @@ export function calculateBWXY(
} else if (typeEffectiveness === 0 && move.hasType('Ground') &&
defender.hasItem('Iron Ball') && !defender.hasAbility('Klutz')) {
typeEffectiveness = 1;
} else if (typeEffectiveness === 0 && defender.hasItem('Ring Target')) {
const effectiveness = gen.types.get(toID(move.type))!.effectiveness;
if (effectiveness[defender.types[0]]! === 0) {
typeEffectiveness = type2Effectiveness;
} else if (defender.types[1] && effectiveness[defender.types[1]]! === 0) {
typeEffectiveness = type1Effectiveness;
}
}

if (typeEffectiveness === 0) {
Expand Down
19 changes: 11 additions & 8 deletions calc/src/mechanics/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,19 +140,22 @@ export function getMoveEffectiveness(
isGravity?: boolean,
isRingTarget?: boolean,
) {
if ((isRingTarget || isGhostRevealed) && type === 'Ghost' && move.hasType('Normal', 'Fighting')) {
if (isGhostRevealed && type === 'Ghost' && move.hasType('Normal', 'Fighting')) {
return 1;
} else if ((isRingTarget || isGravity) && type === 'Flying' && move.hasType('Ground')) {
} else if (isGravity && type === 'Flying' && move.hasType('Ground')) {
return 1;
} else if (move.named('Freeze-Dry') && type === 'Water') {
return 2;
} else if (move.named('Flying Press')) {
return (
gen.types.get('fighting' as ID)!.effectiveness[type]! *
gen.types.get('flying' as ID)!.effectiveness[type]!
);
} else {
return gen.types.get(toID(move.type))!.effectiveness[type]!;
let effectiveness = gen.types.get(toID(move.type))!.effectiveness[type]!;
if (effectiveness === 0 && isRingTarget) {
effectiveness = 1;
}
if (move.named('Flying Press')) {
// Can only do this because flying has no other interactions
effectiveness *= gen.types.get('flying' as ID)!.effectiveness[type]!;
}
return effectiveness;
}
}

Expand Down
54 changes: 54 additions & 0 deletions calc/src/test/calc.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,43 @@ describe('calc', () => {
});
});

inGens(6, 9, ({gen, calculate, Pokemon, Move}) => {
test(`Flying Press (gen ${gen})`, () => {
const attacker = Pokemon('Hawlucha');
const flyingPress = Move('Flying Press');
// Test it is 4x dmg if weak to flying and fighting
const result = calculate(attacker, Pokemon('Cacturne'), flyingPress);
if (gen === 6) {
expect(result.range()).toEqual([484, 576]);
expect(result.desc()).toBe(
'0 Atk Hawlucha Flying Press vs. 0 HP / 0 Def Cacturne: 484-576 (172.2 - 204.9%) -- guaranteed OHKO'
);
} else {
expect(result.range()).toEqual([612, 720]);
expect(result.desc()).toBe(
'0 Atk Hawlucha Flying Press vs. 0 HP / 0 Def Cacturne: 612-720 (217.7 - 256.2%) -- guaranteed OHKO'
);
}

// Test still maintains fighting immunities
const result2 = calculate(attacker, Pokemon('Spiritomb'), flyingPress);
expect(result2.range()).toEqual([0, 0]);

// Test fighting immunities can be overridden
const scrappyAttacker = Pokemon('Hawlucha', {'ability': 'Scrappy'});
const ringTargetSpiritomb = Pokemon('Spiritomb', {'item': 'Ring Target'});
const result3 = calculate(attacker, ringTargetSpiritomb, flyingPress);
const result4 = calculate(scrappyAttacker, Pokemon('Spiritomb'), flyingPress);
if (gen === 6) {
expect(result3.range()).toEqual([152, 180]);
expect(result4.range()).toEqual([152, 180]);
} else {
expect(result3.range()).toEqual([188, 224]);
expect(result4.range()).toEqual([188, 224]);
}
});
});

inGens(6, 9, ({gen, calculate, Pokemon, Move}) => {
test(`Thousand Arrows and Ring Target Should negate damage nullfiers (gen ${gen})`, () => {
const result = calculate(Pokemon('Zygarde'), Pokemon('Swellow'), Move('Thousand Arrows'));
Expand All @@ -208,6 +245,23 @@ describe('calc', () => {
});
});

inGens(5, 9, ({gen, calculate, Pokemon, Move}) => {
test(`Ring Target should negate type nullfiers (gen ${gen})`, () => {
const attacker = Pokemon('Mew');
const defender = Pokemon('Skarmory', {'item': 'Ring Target'});
const result = calculate(attacker, defender, Move('Sludge Bomb'));
expect(result.range()).toEqual([87, 103]);
expect(result.desc()).toBe(
'0 SpA Mew Sludge Bomb vs. 0 HP / 0 SpD Skarmory: 87-103 (32.1 - 38%) -- 94.6% chance to 3HKO'
);
const result2 = calculate(attacker, defender, Move('Earth Power'));
expect(result2.range()).toEqual([174, 206]);
expect(result2.desc()).toBe(
'0 SpA Mew Earth Power vs. 0 HP / 0 SpD Skarmory: 174-206 (64.2 - 76%) -- guaranteed 2HKO'
);
});
});

describe('IVs are shown if applicable', () => {
inGens(3, 9, ({gen, calculate, Pokemon, Move}) => {
test(`Gen ${gen}`, () => {
Expand Down

0 comments on commit 9e56c00

Please sign in to comment.