mirror of
https://github.com/smogon/pokemon-showdown.git
synced 2026-04-26 02:39:38 -05:00
It turns out not creating a format on-the-fly breaks deserialization. We now just use the same custom-rule system that tournaments use. Some hacks are currently necessary (many tests assume that we're playing in Anything Goes rather than Custom Game) but we'll work them out in time.
196 lines
8.3 KiB
JavaScript
196 lines
8.3 KiB
JavaScript
'use strict';
|
|
|
|
const assert = require('./../../assert');
|
|
const common = require('./../../common');
|
|
|
|
let battle;
|
|
|
|
describe('Curse', function () {
|
|
afterEach(function () {
|
|
battle.destroy();
|
|
});
|
|
|
|
it('should request the Ghost target if the user is a known Ghost', function () {
|
|
battle = common.createBattle();
|
|
battle.setPlayer('p1', {team: [{species: "Gengar", ability: 'levitate', item: '', moves: ['curse']}]});
|
|
battle.setPlayer('p2', {team: [{species: "Caterpie", ability: 'shedskin', item: '', moves: ['stringshot']}]});
|
|
assert.strictEqual(battle.p1.active[0].getRequestData().moves[0].target, 'normal');
|
|
});
|
|
|
|
it('should request the Ghost target after the user becomes Ghost', function () {
|
|
battle = common.createBattle();
|
|
battle.setPlayer('p1', {team: [{species: "Rapidash", ability: 'levitate', item: '', moves: ['curse']}]});
|
|
battle.setPlayer('p2', {team: [{species: "Trevenant", ability: 'shedskin', item: 'laggingtail', moves: ['trickortreat']}]});
|
|
|
|
assert.strictEqual(battle.p1.active[0].getRequestData().moves[0].target, 'self');
|
|
battle.makeChoices('auto', 'auto');
|
|
assert.strictEqual(battle.p1.active[0].getRequestData().moves[0].target, 'normal');
|
|
});
|
|
|
|
it('should not request a target after the user stops being Ghost', function () {
|
|
battle = common.createBattle();
|
|
battle.setPlayer('p1', {team: [{species: "Gengar", ability: 'levitate', item: '', moves: ['curse']}]});
|
|
battle.setPlayer('p2', {team: [{species: "Jellicent", ability: 'waterabsorb', item: '', moves: ['soak']}]});
|
|
|
|
assert.strictEqual(battle.p1.active[0].getRequestData().moves[0].target, 'normal');
|
|
battle.makeChoices('auto', 'auto');
|
|
assert.strictEqual(battle.p1.active[0].getRequestData().moves[0].target, 'self');
|
|
});
|
|
|
|
it('should not request a target if the user is a known non-Ghost', function () {
|
|
battle = common.createBattle();
|
|
battle.setPlayer('p1', {team: [{species: "Blastoise", ability: 'torrent', item: '', moves: ['curse']}]});
|
|
battle.setPlayer('p2', {team: [{species: "Caterpie", ability: 'shedskin', item: '', moves: ['stringshot']}]});
|
|
assert.strictEqual(battle.p1.active[0].getRequestData().moves[0].target, 'self');
|
|
});
|
|
|
|
it('should not request a target if the user is an unknown non-Ghost', function () {
|
|
battle = common.createBattle();
|
|
battle.setPlayer('p1', {team: [{species: "Blastoise", ability: 'torrent', item: '', moves: ['curse', 'reflecttype']}]});
|
|
battle.setPlayer('p2', {team: [
|
|
{species: "Zoroark", ability: 'illusion', item: '', moves: ['nastyplot']},
|
|
{species: "Gengar", ability: 'levitate', item: '', moves: ['spite']},
|
|
]});
|
|
battle.makeChoices('move reflecttype', 'auto'); // Reflect Type!
|
|
|
|
assert.deepEqual(battle.p1.active[0].getTypes(), ["Dark"]); // Copied Zoroark's type instead of Gengar's
|
|
assert.strictEqual(battle.p1.active[0].getRequestData().moves[0].target, 'self');
|
|
});
|
|
|
|
it('should curse a non-Ghost user with Protean', function () {
|
|
battle = common.createBattle();
|
|
battle.setPlayer('p1', {team: [{species: "Greninja", ability: 'protean', item: '', moves: ['curse', 'spite']}]});
|
|
battle.setPlayer('p2', {team: [{species: "Caterpie", ability: 'shedskin', item: '', moves: ['stringshot']}]});
|
|
|
|
battle.makeChoices('auto', 'auto');
|
|
let hps = [battle.p1.active[0].hp, battle.p2.active[0].hp];
|
|
assert.notStrictEqual(hps[0], battle.p1.active[0].maxhp); // Curse user cut its HP down + residual damage
|
|
assert.strictEqual(hps[1], battle.p2.active[0].maxhp); // Foe unaffected
|
|
|
|
battle.makeChoices('move spite', 'auto');
|
|
assert.notStrictEqual(hps[0], battle.p1.active[0].hp); // Curse user is hurt by residual damage
|
|
assert.strictEqual(hps[1], battle.p2.active[0].hp); // Foe unaffected
|
|
});
|
|
|
|
it('should curse the target if a Ghost user has Protean', function () {
|
|
battle = common.createBattle();
|
|
battle.setPlayer('p1', {team: [{species: "Gengar", ability: 'protean', item: '', moves: ['curse', 'spite']}]});
|
|
battle.setPlayer('p2', {team: [{species: "Caterpie", ability: 'shedskin', item: '', moves: ['stringshot']}]});
|
|
|
|
battle.makeChoices('auto', 'auto');
|
|
let hps = [battle.p1.active[0].hp, battle.p2.active[0].hp];
|
|
assert.notStrictEqual(hps[0], battle.p1.active[0].maxhp); // Curse user cut its HP down
|
|
assert.notStrictEqual(hps[1], battle.p2.active[0].maxhp); // Curse residual damage
|
|
|
|
battle.makeChoices('move spite', 'auto');
|
|
// Check residual damage
|
|
assert.strictEqual(hps[0], battle.p1.active[0].hp); // Curse user unaffected
|
|
assert.notStrictEqual(hps[1], battle.p2.active[0].hp); // Curse residual damage
|
|
});
|
|
});
|
|
|
|
describe('XY/ORAS Curse targetting when becoming Ghost the same turn', function () {
|
|
afterEach(function () {
|
|
battle.destroy();
|
|
});
|
|
|
|
let doublesTeams = [[
|
|
{species: "Kecleon", ability: 'colorchange', item: 'laggingtail', moves: ['curse', 'calmmind']},
|
|
{species: "Sableye", ability: 'prankster', item: '', moves: ['lightscreen', 'mudsport']},
|
|
], [
|
|
{species: "Raikou", ability: 'pressure', item: '', moves: ['aurasphere', 'calmmind']},
|
|
{species: "Gastly", ability: 'levitate', item: '', moves: ['lick', 'calmmind']},
|
|
]];
|
|
|
|
let triplesTeams = [
|
|
doublesTeams[0].concat({species: "Metapod", ability: 'shedskin', item: '', moves: ['harden', 'stringshot']}),
|
|
doublesTeams[1].concat({species: "Kakuna", ability: 'shedskin', item: '', moves: ['harden', 'stringshot']}),
|
|
];
|
|
|
|
function runDoublesTest(battle, curseUser) {
|
|
let p2active = battle.p2.active;
|
|
let cursePartner = curseUser.side.active[1 - curseUser.position];
|
|
|
|
battle.makeChoices(
|
|
// p1: Kecleon uses Curse last in the turn.
|
|
// p2: Fighting attack on Kecleon, then Ghost.
|
|
`move 1, move 1`,
|
|
`move aurasphere ${curseUser.position + 1}, move lick ${curseUser.position + 1}`
|
|
);
|
|
|
|
assert.ok(curseUser.hasType('Ghost')); // Curse user must be Ghost
|
|
assert.ok(curseUser.hp < curseUser.maxhp / 2); // Curse user cut its HP down
|
|
|
|
let foeHP = [p2active[0].hp, p2active[1].hp];
|
|
battle.makeChoices(
|
|
`move 2, move 2`,
|
|
`move 2, move 2`);
|
|
|
|
assert.notStrictEqual(curseUser.hp, curseUser.maxhp); // Curse user cut its HP down
|
|
if (curseUser.position === 0) {
|
|
// Expected behavior
|
|
assert.strictEqual(cursePartner.hp, cursePartner.maxhp); // Partner unaffected by Curse
|
|
assert.ok(foeHP[0] !== p2active[0].maxhp || foeHP[1] !== p2active[1].maxhp); // Foe afflicted by Curse
|
|
} else {
|
|
// Cartridge glitch
|
|
assert.notStrictEqual(cursePartner.hp, cursePartner.maxhp); // Partner afflicted by Curse
|
|
assert.ok(foeHP[0] === p2active[0].maxhp && foeHP[1] === p2active[1].maxhp); // Foes unaffected by Curse
|
|
}
|
|
}
|
|
|
|
function runTriplesTest(battle, curseUser) {
|
|
let p1active = battle.p1.active;
|
|
let p2active = battle.p2.active;
|
|
|
|
battle.makeChoices(
|
|
// p1: Kecleon uses Curse last in the turn.
|
|
// p2: Electric attack on Kecleon, then Ghost.
|
|
`move 1, move 1, move 1`,
|
|
`move aurasphere ${curseUser.position + 1}, move lick ${curseUser.position + 1}, move harden`
|
|
);
|
|
|
|
assert.ok(curseUser.hasType('Ghost')); // Curse user must be Ghost
|
|
assert.ok(curseUser.hp < curseUser.maxhp / 2); // Curse user cut its HP down
|
|
|
|
let cursedFoe = false;
|
|
for (let i = 0; i < 3; i++) {
|
|
let allyPokemon = p1active[i];
|
|
if (allyPokemon === curseUser) {
|
|
assert.notStrictEqual(allyPokemon.hp, allyPokemon.maxhp); // Curse user cut its HP down
|
|
} else {
|
|
assert.strictEqual(allyPokemon.hp, allyPokemon.maxhp); // Partners unaffected by Curse
|
|
}
|
|
|
|
let foePokemon = p2active[i];
|
|
if (foePokemon.hp !== foePokemon.maxhp) {
|
|
cursedFoe = true;
|
|
}
|
|
}
|
|
assert.ok(cursedFoe);
|
|
}
|
|
|
|
it('should target an opponent in Doubles if the user is on left side and becomes Ghost the same turn', function () {
|
|
battle = common.createBattle({gameType: 'doubles'}, doublesTeams.slice());
|
|
runDoublesTest(battle, battle.p1.active[0]);
|
|
});
|
|
|
|
it('should target the ally in Doubles if the user is on right side and becomes Ghost the same turn', function () {
|
|
battle = common.createBattle({gameType: 'doubles'}, [
|
|
[doublesTeams[0][1], doublesTeams[0][0]],
|
|
doublesTeams[1],
|
|
]);
|
|
runDoublesTest(battle, battle.p1.active[1]);
|
|
});
|
|
|
|
for (let cursePos of [0, 1, 2]) {
|
|
it('should target an opponent in Triples even if the user is on position ' + cursePos, function () {
|
|
let p1team = triplesTeams[0].slice(1);
|
|
p1team.splice(cursePos, 0, triplesTeams[0][0]);
|
|
let p2team = triplesTeams[1].slice();
|
|
|
|
battle = common.gen(5).createBattle({gameType: 'triples'}, [p1team, p2team]);
|
|
runTriplesTest(battle, battle.p1.active[cursePos]);
|
|
});
|
|
}
|
|
});
|