Pokemon_server / test /sim /moves /futuresight.js
Jofthomas's picture
Jofthomas HF staff
Upload 4781 files
5c2ed06 verified
'use strict';
const assert = require('./../../assert');
const common = require('./../../common');
let battle;
describe('Future Sight', () => {
afterEach(() => {
battle.destroy();
});
it(`should damage in two turns, ignoring Protect, affected by Dark immunities`, () => {
battle = common.createBattle([[
{ species: 'Sneasel', moves: ['sleeptalk', 'futuresight'] },
], [
{ species: 'Girafarig', moves: ['sleeptalk', 'futuresight', 'protect'] },
]]);
const sneasel = battle.p1.active[0];
const girafarig = battle.p2.active[0];
battle.makeChoices('move futuresight', 'move futuresight');
assert.fullHP(girafarig);
battle.makeChoices();
assert.fullHP(girafarig);
battle.makeChoices('auto', 'move protect');
assert.fullHP(sneasel);
assert.false.fullHP(girafarig);
});
it(`should fail when already active for the target's position`, () => {
battle = common.createBattle([[
{ species: 'Sneasel', moves: ['sleeptalk'] },
], [
{ species: 'Girafarig', moves: ['futuresight'] },
]]);
battle.makeChoices();
battle.makeChoices();
assert(battle.log[battle.lastMoveLine + 1].startsWith('|-fail|'));
});
it(`[Gen 2] should damage in two turns, ignoring Protect`, () => {
battle = common.gen(2).createBattle([[
{ species: 'Sneasel', moves: ['sleeptalk', 'futuresight', 'sweetscent'] },
], [
{ species: 'Girafarig', moves: ['sleeptalk', 'futuresight', 'protect', 'sweetscent'] },
]]);
const sneasel = battle.p1.active[0];
const girafarig = battle.p2.active[0];
battle.makeChoices('move sweetscent', 'move sweetscent'); // counteract imperfect accuracy
battle.makeChoices('move futuresight', 'move futuresight');
assert.fullHP(girafarig);
battle.makeChoices('auto', 'auto');
assert.fullHP(girafarig);
battle.makeChoices('auto', 'move Protect');
assert.false.fullHP(sneasel);
assert.false.fullHP(girafarig);
});
it(`should not double Stomping Tantrum for exiting normally`, () => {
battle = common.createBattle([[
{ species: 'Wynaut', moves: ['futuresight', 'stompingtantrum'] },
], [
{ species: 'Scizor', ability: 'shellarmor', moves: ['sleeptalk'] },
]]);
battle.makeChoices();
battle.makeChoices('move stompingtantrum', 'move sleeptalk');
const scizor = battle.p2.active[0];
const damage = scizor.maxhp - scizor.hp;
assert.bounded(damage, [19, 23]); // If it were doubled, would be 38-45
});
it(`should not trigger Eject Button`, () => {
battle = common.createBattle([[
{ species: 'Wynaut', moves: ['futuresight'] },
], [
{ species: 'Scizor', item: 'ejectbutton', moves: ['sleeptalk'] },
{ species: 'Roggenrola', moves: ['sleeptalk'] },
]]);
for (let i = 0; i < 3; i++) battle.makeChoices();
assert.equal(battle.requestState, 'move');
});
it(`should be able to set Future Sight against an empty target slot`, () => {
battle = common.createBattle([[
{ species: 'Shedinja', moves: ['finalgambit'] },
{ species: 'Roggenrola', moves: ['sleeptalk'] },
], [
{ species: 'Wynaut', moves: ['sleeptalk', 'futuresight'] },
]]);
battle.makeChoices('auto', 'move future sight');
battle.makeChoices('switch 2');
battle.makeChoices();
battle.makeChoices();
const roggenrola = battle.p1.active[0];
assert.false.fullHP(roggenrola);
});
it(`its damaging hit should not count as copyable for Copycat`, () => {
battle = common.createBattle([[
{ species: 'Wynaut', moves: ['sleeptalk', 'futuresight'] },
], [
{ species: 'Liepard', moves: ['sleeptalk', 'copycat'] },
]]);
battle.makeChoices('move futuresight', 'auto');
battle.makeChoices();
battle.makeChoices();
battle.makeChoices('auto', 'move copycat'); // Should fail due to last move being Sleep Talk
battle.makeChoices();
battle.makeChoices();
const wynaut = battle.p1.active[0];
assert.fullHP(wynaut);
});
it(`should only cause the user to take Life Orb recoil on its damaging turn`, () => {
battle = common.createBattle([[
{ species: 'wynaut', item: 'lifeorb', moves: ['futuresight'] },
], [
{ species: 'mew', moves: ['sleeptalk'] },
]]);
battle.makeChoices();
const wynaut = battle.p1.active[0];
const mew = battle.p2.active[0];
assert.fullHP(wynaut, `Wynaut should not take Life Orb recoil on Future Sight's starting turn`);
battle.makeChoices();
battle.makeChoices();
assert.equal(wynaut.hp, wynaut.maxhp - Math.floor(wynaut.maxhp / 10), `Wynaut should take Life Orb recoil on Future Sight's damaging turn`);
const damage = mew.maxhp - mew.hp;
assert.bounded(damage, [30, 35]); // 22-27 if Life Orb was not applied
});
it(`[Gen 4] should not be affected by Life Orb`, () => {
battle = common.gen(4).createBattle([[
{ species: 'wynaut', item: 'lifeorb', moves: ['futuresight'] },
], [
{ species: 'mew', ability: 'noguard', moves: ['sleeptalk'] },
]]);
battle.makeChoices();
const wynaut = battle.p1.active[0];
const mew = battle.p2.active[0];
battle.makeChoices();
battle.makeChoices();
assert.fullHP(wynaut, `Wynaut should not have taken any damage`);
const damage = mew.maxhp - mew.hp;
assert.bounded(damage, [21, 25]); // [27-32] if Life Orb was applied
});
it(`should not be affected by Life Orb if not the original user`, () => {
battle = common.createBattle([[
{ species: 'wynaut', item: 'lifeorb', moves: ['futuresight'] },
{ species: 'liepard', item: 'lifeorb', moves: ['sleeptalk'] },
], [
{ species: 'mew', moves: ['sleeptalk'] },
]]);
battle.makeChoices();
const liepard = battle.p1.pokemon[1];
const mew = battle.p2.active[0];
battle.makeChoices();
battle.makeChoices('switch 2', 'move sleeptalk');
assert.fullHP(liepard, `liepard should not have taken any damage`);
const damage = mew.maxhp - mew.hp;
assert.bounded(damage, [22, 27]); // 30, 35 if Life Orb was applied
});
it(`should not cause the user to change typing on either its starting or damaging turn`, () => {
battle = common.createBattle([[
{ species: 'roggenrola', ability: 'protean', moves: ['futuresight', 'sleeptalk'] },
], [
{ species: 'mew', moves: ['sleeptalk'] },
]]);
const roggenrola = battle.p1.active[0];
battle.makeChoices();
assert.false(roggenrola.hasType('Psychic'), `Protean Roggenrola should not change type on Future Sight's starting turn`);
battle.makeChoices();
battle.makeChoices();
assert.false(roggenrola.hasType('Psychic'), `Protean Roggenrola should not change type on Future Sight's damaging turn`);
});
it(`should be boosted by Terrain only if Terrain is active on the damaging turn`, () => {
battle = common.createBattle([[
{ species: 'Blissey', ability: 'shellarmor', moves: ['softboiled'] },
], [
{ species: 'Wynaut', ability: 'psychicsurge', moves: ['sleeptalk', 'futuresight'] },
]]);
battle.makeChoices('auto', 'move futuresight');
battle.makeChoices();
battle.makeChoices();
const blissey = battle.p1.active[0];
let damage = blissey.maxhp - blissey.hp;
assert.bounded(damage, [46, 55]);
battle.makeChoices('auto', 'move futuresight');
battle.makeChoices();
battle.makeChoices();
damage = blissey.maxhp - blissey.hp;
assert.bounded(damage, [36, 43]);
});
it(`should be boosted by Terrain even if the user is not on the field, as long as the user is not Flying-type`, () => {
battle = common.createBattle([[
{ species: 'Blissey', ability: 'shellarmor', moves: ['softboiled'] },
], [
{ species: 'cresselia', ability: 'levitate', moves: ['sleeptalk', 'futuresight'] },
{ species: 'deino', ability: 'psychicsurge', moves: ['sleeptalk'] },
{ species: 'xatu', moves: ['sleeptalk', 'futuresight'] },
]]);
// Cresselia will be Terrain-boosted because its Ability is not checked while not active
battle.makeChoices('auto', 'move futuresight');
battle.makeChoices();
battle.makeChoices('auto', 'switch deino');
const blissey = battle.p1.active[0];
let damage = blissey.maxhp - blissey.hp;
assert.bounded(damage, [102, 121]);
// Xatu won't be Terrain-boosted because its Flying-type is checked while not active
battle.makeChoices('auto', 'switch xatu');
battle.makeChoices('auto', 'move futuresight');
battle.makeChoices();
battle.makeChoices('auto', 'switch deino');
damage = blissey.maxhp - blissey.hp;
assert.bounded(damage, [96, 114]);
});
it(`should not ignore the target's screens, even when the user is not active on the field`, () => {
battle = common.createBattle([[
{ species: 'Blissey', ability: 'shellarmor', item: 'lightclay', moves: ['softboiled', 'lightscreen'] },
], [
{ species: 'Wynaut', moves: ['sleeptalk', 'futuresight'] },
{ species: 'deino', moves: ['sleeptalk'] },
]]);
battle.makeChoices('move lightscreen', 'move futuresight');
battle.makeChoices();
battle.makeChoices();
const blissey = battle.p1.active[0];
let damage = blissey.maxhp - blissey.hp;
assert.bounded(damage, [18, 21]);
battle.makeChoices('auto', 'move futuresight');
battle.makeChoices();
battle.makeChoices('auto', 'switch 2');
damage = blissey.maxhp - blissey.hp;
assert.bounded(damage, [18, 21]);
});
it(`should not consider the user's item or Ability when the user is not active`, () => {
battle = common.createBattle([[
{ species: 'Blissey', ability: 'shellarmor', moves: ['softboiled'] },
], [
{ species: 'Wynaut', ability: 'adaptability', item: 'choicespecs', moves: ['futuresight'] },
{ species: 'Deino', ability: 'powerspot', moves: ['sleeptalk'] },
]]);
for (let i = 0; i < 3; i++) battle.makeChoices();
const blissey = battle.p1.active[0];
let damage = blissey.maxhp - blissey.hp;
assert.bounded(damage, [70, 84]); // boosted by Adaptability and Choice Specs
battle.makeChoices();
battle.makeChoices();
battle.makeChoices('auto', 'switch 2');
damage = blissey.maxhp - blissey.hp;
assert.bounded(damage, [46, 55]); // only boosted by Power Spot
});
it(`should not ignore the target's Unaware`, () => {
battle = common.createBattle([[
{ species: 'Manaphy', ability: 'simple', moves: ['tailglow', 'futuresight'] },
], [
{ species: 'Ho-Oh', ability: 'unaware', moves: ['luckychant'] },
]]);
battle.makeChoices();
battle.makeChoices('move futuresight', 'auto');
battle.makeChoices();
battle.makeChoices();
const hooh = battle.p2.active[0];
const damage = hooh.maxhp - hooh.hp;
assert.bounded(damage, [60, 71]); // Damage would be 236-278 if Unaware was being ignored
});
it(`should use the user's most recent Special Attack stat if the user is on the field`, () => {
battle = common.createBattle([[
{ species: 'Aegislash', ability: 'stancechange', moves: ['futuresight', 'kingsshield'] },
], [
{ species: 'Ho-Oh', ability: 'shellarmor', moves: ['recover'] },
]]);
for (let i = 0; i < 3; i++) battle.makeChoices();
const hooh = battle.p2.active[0];
let damage = hooh.maxhp - hooh.hp;
assert.bounded(damage, [79, 94]); // Blade Forme damage
battle.makeChoices();
battle.makeChoices('move kingsshield', 'auto');
battle.makeChoices('move kingsshield', 'auto');
damage = hooh.maxhp - hooh.hp;
assert.bounded(damage, [34, 41]); // Shield Forme damage
});
it.skip(`should use the user's most recent Special Attack stat, even if the user is not on the field`, () => {
battle = common.createBattle([[
{ species: 'Aegislash', ability: 'stancechange', moves: ['futuresight', 'kingsshield'] },
{ species: 'Wynaut', moves: ['sleeptalk'] },
], [
{ species: 'Ho-Oh', ability: 'shellarmor', moves: ['recover', 'flareblitz'] },
]]);
battle.makeChoices();
battle.makeChoices('switch wynaut', 'auto');
battle.makeChoices();
const hooh = battle.p2.active[0];
let damage = hooh.maxhp - hooh.hp;
assert.bounded(damage, [79, 94], `Future Sight should deal Blade Forme damage, even though Aegislash switched out in Blade Forme`);
battle.makeChoices('switch aegislash', 'auto');
battle.makeChoices();
battle.makeChoices('auto', 'move flareblitz');
battle.makeChoices(); // switch in Wynaut
battle.makeChoices();
damage = hooh.maxhp - hooh.hp;
assert.bounded(damage, [79, 94], `Future Sight should deal Blade Forme damage, even though Aegislash was KOed in Blade Forme.`);
});
it(`should only use Sp. Atk stat boosts/drops if the user is on the field`, () => {
battle = common.createBattle([[
{ species: 'Flapple', moves: ['futuresight', 'nastyplot', 'sleeptalk'] },
{ species: 'Wynaut', moves: ['sleeptalk'] },
], [
{ species: 'Ho-Oh', ability: 'shellarmor', moves: ['recover'] },
]]);
battle.makeChoices();
battle.makeChoices('move nastyplot', 'auto');
battle.makeChoices();
const hooh = battle.p2.active[0];
let damage = hooh.maxhp - hooh.hp;
assert.bounded(damage, [113, 134], `Future Sight should deal damage with +2 Sp. Atk`);
battle.makeChoices();
battle.makeChoices('switch wynaut', 'auto');
battle.makeChoices();
damage = hooh.maxhp - hooh.hp;
assert.bounded(damage, [57, 68], `Future Sight should deal damage with +0 Sp. Atk`);
});
it(`should never resolve when used on turn 254 or later`, () => {
battle = common.createBattle([[
{ species: 'Wynaut', moves: ['sleeptalk', 'futuresight'] },
], [
{ species: 'Stakataka', moves: ['sleeptalk'] },
]]);
battle.turn = 255; // Showdown turn is +1 from what the games are; this would ordinarily be 254
battle.makeChoices('move futuresight', 'auto');
for (let i = 0; i < 5; i++) battle.makeChoices();
battle.makeChoices('move futuresight', 'auto');
for (let i = 0; i < 5; i++) battle.makeChoices();
const stak = battle.p2.active[0];
assert.fullHP(stak, `Future Sight should have never resolved.`);
});
it(`should target particular slots in Doubles`, () => {
battle = common.createBattle({ gameType: 'doubles' }, [[
{ species: 'Wynaut', moves: ['sleeptalk', 'futuresight'] },
{ species: 'Steelix', moves: ['sleeptalk'] },
], [
{ species: 'Girafarig', moves: ['sleeptalk', 'recover'] },
{ species: 'Farigiraf', moves: ['sleeptalk', 'recover'] },
]]);
battle.makeChoices('move futuresight 2, auto', 'auto');
battle.makeChoices();
battle.makeChoices();
const giraf = battle.p2.active[0];
const farig = battle.p2.active[1];
assert.false.fullHP(farig, `Farigiraf should have been damaged by the 1st Future Sight.`);
battle.makeChoices('move futuresight 1, auto', 'move recover, move recover');
battle.makeChoices();
battle.makeChoices();
assert.false.fullHP(giraf, `Girafarig should have been damaged by the 2nd Future Sight.`);
battle.makeChoices('move futuresight -2, auto', 'auto');
battle.makeChoices();
battle.makeChoices();
const steelix = battle.p1.active[1];
assert.false.fullHP(steelix, `Steelix should have been damaged by the 3rd Future Sight`);
});
it(`should do nothing if no Pokemon is present to take damage from the Future attack`, () => {
battle = common.createBattle([[
{ species: 'Wynaut', ability: 'magicguard', moves: ['sleeptalk'] },
{ species: 'Shedinja', moves: ['sleeptalk'] },
], [
{ species: 'Happiny', moves: ['stealthrock', 'futuresight'] },
]]);
battle.makeChoices('auto', 'move futuresight');
battle.makeChoices('auto', 'move stealthrock');
battle.makeChoices('switch 2', 'auto');
battle.makeChoices('switch 2');
battle.makeChoices();
const wynaut = battle.p1.active[0];
assert.fullHP(wynaut);
});
});