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 GSC Toxic interaction with Baton Pass/Heal Bell #5226

Merged
merged 10 commits into from
Mar 5, 2019
39 changes: 3 additions & 36 deletions data/mods/gen1/statuses.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,12 @@ let BattleStatuses = {
},
onAfterMoveSelfPriority: 2,
onAfterMoveSelf(pokemon) {
let toxicCounter = 1;
if (pokemon.volatiles['residualdmg']) {
pokemon.volatiles['residualdmg'].counter++;
toxicCounter = pokemon.volatiles['residualdmg'].counter;
}
let toxicCounter = pokemon.volatiles['residualdmg'] ? pokemon.volatiles['residualdmg'].counter : 1;
this.damage(this.clampIntRange(Math.floor(pokemon.maxhp / 16), 1) * toxicCounter, pokemon);
},
onSwitchIn(pokemon) {
pokemon.addVolatile('brnattackdrop');
},
onAfterSwitchInSelf(pokemon) {
this.damage(this.clampIntRange(Math.floor(pokemon.maxhp / 16), 1));
},
},
par: {
name: 'par',
Expand Down Expand Up @@ -118,39 +111,13 @@ let BattleStatuses = {
},
onAfterMoveSelfPriority: 2,
onAfterMoveSelf(pokemon) {
let toxicCounter = 1;
if (pokemon.volatiles['residualdmg']) {
pokemon.volatiles['residualdmg'].counter++;
toxicCounter = pokemon.volatiles['residualdmg'].counter;
}
let toxicCounter = pokemon.volatiles['residualdmg'] ? pokemon.volatiles['residualdmg'].counter : 1;
this.damage(this.clampIntRange(Math.floor(pokemon.maxhp / 16), 1) * toxicCounter, pokemon);
},
onAfterSwitchInSelf(pokemon) {
this.damage(this.clampIntRange(Math.floor(pokemon.maxhp / 16), 1));
},
},
tox: {
name: 'tox',
id: 'tox',
num: 0,
effectType: 'Status',
onStart(target) {
this.add('-status', target, 'tox');
if (!target.volatiles['residualdmg']) target.addVolatile('residualdmg');
target.volatiles['residualdmg'].counter = 0;
},
inherit: true,
onAfterMoveSelfPriority: 2,
onAfterMoveSelf(pokemon) {
pokemon.volatiles['residualdmg'].counter++;
this.damage(this.clampIntRange(Math.floor(pokemon.maxhp / 16), 1) * pokemon.volatiles['residualdmg'].counter, pokemon, pokemon);
},
onSwitchIn(pokemon) {
// Regular poison status and damage after a switchout -> switchin.
pokemon.setStatus('psn');
},
onAfterSwitchInSelf(pokemon) {
this.damage(this.clampIntRange(Math.floor(pokemon.maxhp / 16), 1));
},
},
confusion: {
name: 'confusion',
Expand Down
42 changes: 32 additions & 10 deletions data/mods/gen2/statuses.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ let BattleStatuses = {
},
onAfterMoveSelfPriority: 3,
onAfterMoveSelf(pokemon) {
this.damage(pokemon.maxhp / 8);
residualdmg(this, pokemon);
},
onAfterSwitchInSelf(pokemon) {
this.damage(pokemon.maxhp / 8);
residualdmg(this, pokemon);
},
},
par: {
Expand Down Expand Up @@ -89,10 +89,10 @@ let BattleStatuses = {
},
onAfterMoveSelfPriority: 3,
onAfterMoveSelf(pokemon) {
this.damage(pokemon.maxhp / 8);
residualdmg(this, pokemon);
},
onAfterSwitchInSelf(pokemon) {
this.damage(pokemon.maxhp / 8);
residualdmg(this, pokemon);
},
},
tox: {
Expand All @@ -102,18 +102,15 @@ let BattleStatuses = {
effectType: 'Status',
onStart(target) {
this.add('-status', target, 'tox');
this.effectData.stage = 0;
if (!target.volatiles['residualdmg']) target.addVolatile('residualdmg');
target.volatiles['residualdmg'].counter = 0;
},
onAfterMoveSelfPriority: 3,
onAfterMoveSelf(pokemon) {
if (this.effectData.stage < 15) {
this.effectData.stage++;
}
this.damage(this.clampIntRange(pokemon.maxhp / 16, 1) * this.effectData.stage);
this.damage(this.clampIntRange(Math.floor(pokemon.maxhp / 16), 1) * pokemon.volatiles['residualdmg'].counter, pokemon, pokemon);
},
onSwitchIn(pokemon) {
// Regular poison status and damage after a switchout -> switchin.
this.effectData.stage = 0;
pokemon.setStatus('psn');
},
onAfterSwitchInSelf(pokemon) {
Expand Down Expand Up @@ -226,6 +223,31 @@ let BattleStatuses = {
this.effectData.duration = 2;
},
},
residualdmg: {
name: 'residualdmg',
id: 'residualdmg',
num: 0,
onStart(target) {
target.volatiles['residualdmg'].counter = 0;
},
onAfterMoveSelfPriority: 100,
onAfterMoveSelf(pokemon) {
pokemon.volatiles['residualdmg'].counter++;
},
scheibo marked this conversation as resolved.
Show resolved Hide resolved
},
};

/**
* @param {Battle} battle
* @param {Pokemon} pokemon
*/
function residualdmg(battle, pokemon) {
if (pokemon.volatiles['residualdmg']) {
battle.damage(battle.clampIntRange(Math.floor(pokemon.maxhp / 16) * pokemon.volatiles['residualdmg'].counter, 1), pokemon);
battle.add('-hint', 'In GSC, Toxic\'s counter is retained through Baton Pass/Heal Bell and applies to PSN/BRN.');
scheibo marked this conversation as resolved.
Show resolved Hide resolved
} else {
battle.damage(battle.clampIntRange(Math.floor(pokemon.maxhp / 8), 1), pokemon);
}
}

exports.BattleStatuses = BattleStatuses;
70 changes: 70 additions & 0 deletions test/simulator/misc/statuses.js
Original file line number Diff line number Diff line change
Expand Up @@ -205,3 +205,73 @@ describe('Toxic Poison [Gen 1]', function () {
assert.strictEqual(pokemon.maxhp - pokemon.hp, Math.floor(pokemon.maxhp / 16) * 6);
});
});


describe('Toxic Poison [Gen 2]', function () {
afterEach(function () {
battle.destroy();
});

it('should not affect Leech Seed damage counter', function () {
battle = common.gen(2).createBattle([
[{species: 'Venusaur', moves: ['toxic', 'leechseed']}],
[{species: 'Chansey', moves: ['splash']}],
]);
battle.makeChoices('move toxic', 'move splash');
let pokemon = battle.p2.active[0];
assert.strictEqual(pokemon.maxhp - pokemon.hp, Math.floor(pokemon.maxhp / 16));
battle.makeChoices('move leechseed', 'move splash');
// (1/16) + (2/16) + (1/8) = (5/16)
assert.strictEqual(pokemon.maxhp - pokemon.hp, Math.floor(pokemon.maxhp / 16) * 5);
});

it('should pass the damage counter to Pokemon with Baton Pass', function () {
battle = common.gen(2).createBattle([
[{species: 'Smeargle', moves: ['toxic', 'sacredfire', 'splash']}],
[
{species: 'Chansey', moves: ['splash']},
{species: 'Celebi', moves: ['batonpass', 'splash']},
],
]);
battle.resetRNG(); // Guarantee Sacred Fire burns
battle.makeChoices('move sacredfire', 'move splash');
let pokemon = battle.p2.active[0];
battle.resetRNG(); // Guarantee Toxic hits.
battle.makeChoices('move toxic', 'switch 2');
battle.makeChoices('move splash', 'move splash');
battle.makeChoices('move splash', 'move splash');
battle.makeChoices('move splash', 'move batonpass');
battle.makeChoices('pass', 'switch 2');
let hp = pokemon.hp;
battle.makeChoices('move splash', 'move splash');
assert.strictEqual(hp - pokemon.hp, Math.floor(pokemon.maxhp / 16) * 3);

// Damage counter should be removed on regular switch out
battle.makeChoices('move splash', 'switch 2');
hp = pokemon.hp;
battle.makeChoices('move splash', 'switch 2');
assert.strictEqual(hp - pokemon.hp, Math.floor(pokemon.maxhp / 8));
});

it('should not have its damage counter affected by Heal Bell', function () {
battle = common.gen(2).createBattle([
[{species: 'Smeargle', moves: ['toxic', 'sacredfire', 'splash']}],
[{species: 'Chansey', moves: ['splash', 'healbell']}],
]);
battle.makeChoices('move toxic', 'move splash');
let pokemon = battle.p2.active[0];
battle.makeChoices('move splash', 'move healbell');
battle.resetRNG(); // Guarantee Sacred Fire burns
battle.makeChoices('move sacredfire', 'move splash');
let hp = pokemon.hp;
battle.makeChoices('move splash', 'move splash');
assert.strictEqual(hp - pokemon.hp, Math.floor(pokemon.maxhp / 16) * 4);
hp = pokemon.hp;

battle.makeChoices('move splash', 'move healbell');
battle.resetRNG(); // Guarantee Toxic hits
battle.makeChoices('move toxic', 'move splash');
// Toxic counter should be reset by a successful Toxic
assert.strictEqual(hp - pokemon.hp, Math.floor(pokemon.maxhp / 16));
});
});